解决方案

Linux内核概述

seo靠我 2023-09-24 16:23:08

利用《Grub的概述》引导器,我们终于可以加载内核了。如何获取,编译,修改,发布,是程序员的必修课程。

Linux源码获取

可以在官网下载,这里使用linux-4.15,其包含的内容

arch:体系结构相SEO靠我关的代码,每一个子目录代表一种架构block:块设备的通用函数crypot:常用加密和散列算法、压缩和CRC校核算法fs:Linux支持的文件系统,每一个子目录代表一种文件系统include:内核头文SEO靠我件:基本头文件(include/linux )、驱动或功能部件头文件(例:include/mtd )、体系相关头文件(linux/asm-arm )driver:所有的驱动程序,每一个子目录代表一类驱SEO靠我动程序init:内核的初始化程序,其中main.c中的start_kernel函数是内核引导后执行的第一个函数ipc:进程间的通信代码kernel:内核管理的核心代码,与体系相关的代码在/arch/$SEO靠我(ARCH)/kernellib:内核用到的库函数,与处理器相关的库函数位于/arch/$(ARCH)/libmm:内存管理代码,与处理器体系相关的位于/arch/$(ARCH)/mmnet:与网络相SEO靠我关的代码,每一个子目录对应于网络的一个方面security:安全、密钥相关的代码sound:音频相关的驱动程序usr:用来制作一个压缩的cpio归档文件:initrd的镜像,它可以作为内核启动后挂载的SEO靠我第一个文件系统script:用于配置、编译内核的脚本文件Document:内核文档

内核的编译

最权威的参考资料:/Documentation/Kbuild/makefiles.txt

顶层MakefileSEO靠我    总体上控制着内核的编译arch/$(ARCH)/Makefile    决定哪些和体系相关的代码参加编译.config    配置文件,内核配置时产生,所有的Makefile都根据这个文件编译SEO靠我内核(包括顶层的和各分成的Makefile)scripts/Makefile.*    Makefile公用的通用规则、脚本等*/Makefile    负责该目录下文件的编译

编译哪些文件

顶层MakeSEO靠我file决定哪些目录中的文件将编译进内核。

init-y := init/drivers-y := drivers/ sound/ firmware/net-y := net/libs-y := libSEO靠我/core-y := usr/...core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

顶层Makefile将13个子目录分成5个部分:iniSEO靠我t-y、drivers-y、net-y、libs-y、core-y顶层通过下列语句包含和体系架构有关的Makefile。其中/arch比较特殊, .config文件中,用户配置$(ARCH)参数,来决SEO靠我定其Makefile的。

关于.config文件的生成

内核配置工具读取各个Kconfig文件,生成配置界面共开放人员配置内核,最后生成配置文件.config。

关于Kconfig的最权威资料在/DocumSEO靠我entations/Kbuild/kconfig-language.txt

观察.config文件会发现变量的值主要有两种y、m,各级的Makefile将会根据这些变量的值来决定编译哪些文件,同时是编译SEO靠我进内核,还是作为内核模块存在。

obj-y中定义的.o文件将由当前目录下的.c、.S文件及子目录下的build-in.o文件编译连接得到的。obj-m中定义的.o文件是由的当前目录下的.c、.S文件编译SEO靠我生成,它们不会与build-in.o一起编译进入内核。而是被编译成.ko文件,作为模块存在。

当.o文件由单个文件编译而成时,用下面的语句:

obj-$(CONFIG_ISDN_PPP_BSDCOMP) SEO靠我+= isdn_bsdcomp.o

当.o文件由多种文件编译而成时,用下面的语句:

obj-$(CONFIG_ISDN) +=isdn.o isdn-objs := isdn_net_liSEO靠我b.o isdn_v110.o isdn_commen.o

内核的开发

以linux中的驱动为例,其一般都放在 linux-4.15/drivers/ 目录下,因此在这个目录中创建一个hello文件夹。

$SEO靠我 cd drivers $ mkdir hello

首先是源码,在hello文件夹中创建源文件hello.c

#include <linux/module.h> #inclSEO靠我ude <linux/init.h>// 当驱动被加载的时候,执行此函数 static int __init hello_init(void) {printk(KERNSEO靠我_ALERT "welcome, hello\n");return 0; }// 当驱动被卸载的时候,执行此函数 static void __exit hello_exSEO靠我it(void) {printk(KERN_ALERT "bye, hello\n"); }// 版权声明 MODULE_LICENSE("GPL");SEO靠我// 以下两个函数属于 Linux 的驱动框架,只要把驱动两个函数地址注册进去即可。 module_init(hello_init); module_exit(hellSEO靠我o_exit);

有两个小地方注意一下:

在内核中,打印函数是 printk,而不是 printf;

打印信息的级别有好几个,从 DEBUG 到 EMERG,这里使用的是 KERN_ALERT,方便查看打印SEO靠我信息。

Linux内核整体结构已经很庞大,包含了很多的组件,而对于我们工程师而言,有两种方法将需要的功能包含进内核当中。

将所有的功能都编译进Linux内核。将需要的功能编译成模块,在需要的时候动态地添加SEO靠我

全局编译

创建 Kconfig 文件这个文件是用来对内核进行配置的,当执行 make menuconfig 指令的时候,这个文件就被解析。

config HELLO tristate "SEO靠我hello driver" helpjust a simplest driver. default y

它登记在 linux-4.15/drivers/Kconfig 文SEO靠我件的末尾

source "drivers/hello/Kconfig"endmenu // 加在这一句的上面

执行下面的命令,重新编译。

make distclean make ARCH=xSEO靠我86_64 defconfig make ARCH=x86_64 menuconfig

可以看到 hello driver 前面显示的是型号 *,这表示:该驱动将会编译进内核。

然后创建MSEO靠我akefile文件

obj-$(CONFIG_HELLO) += hello.o##CONFIG_HELLO 可以看做一个变量,在编译的时候,这个变量的值可能是:y, n 或者 m。##在刚才的 KcoSEO靠我nfig 参数配置中,CONFIG_HELLO 被设置为 y,于是这句话就被翻译成: obj-y += hello,表示把 hello 驱动编译进内核。

再把hello目录,加入到driver的MakeSEO靠我file中

obj-$(CONFIG_HELLO) += hello/

万事俱备,只欠编译!依次执行如下指令:

make

编译为驱动模块

编译为驱动模块,也有两种 操作方式:

在执行 make ARCH=x86_SEO靠我64 menuconfig 指令的时候,把 hello 配置成 M;

然后在 linux-4.15 中执行编译模块指令:make -j4 modules。

编译成功之后,就可以得到文件: linux-4.SEO靠我15/drivers/hello/hello.ko。

这样的编译指令,是把所有的模块都编译了一次(在输出信息中,可以看到编译了很多模块)。

只编译 hello 这一个驱动模块

另外一种编译驱动模块的方式是:SEO靠我进入hello目录,只编译这一个驱动模块。

这种编译方法,就需要修改hello目录下的Makefile文件了,内容如下:

可以把 hello 目录下的所有文件删除,只保留源文件 hello.c,然后新建 SEO靠我Makefile 文件。

ifneq ($(KERNELRELEASE),)obj-m := hello.o elseKERNELDIR ?= /lib/modules/$(shell SEO靠我uname -r)/buildPWD := $(shell pwd) default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules SEO靠我clean:$(MAKE) -C $(KERNEL_PATH) M=$(PWD) clean endif

然后,在hello文件夹中执行make指令,即可得到驱动模块 hello.ko SEO靠我

验证

## 加载驱动 sudo insmod ./hello.ko## 可以看到welcome, hello dmesg## 卸载驱动 sudo rmmSEO靠我od hello## 可以看到bye,hello dmesg

主要参考

《Linux内核源码组织结构》

《Linux驱动实践:带你一步一步编译内核驱动程序 》

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2