目录
1. 内核简介
1.1 内核版本及特点
1.2 获取内核源码
1.3 内核启动过程简述
1.3.1 内核引导阶段
1.3.2 内核初始化阶段
2. 内核源码结构及Makefile分析
2.1 Linux内核Makefile分析
2.1.1决定编译那些文件
2.1.2 怎样编译这些文件
2.1.3 怎样链接这些文件
3. Kconfig分析
3.1 Kconfig文件的基本要素
3.1.1 Config条目
3.2.2 Menu条目
3.2.3 Choice条目
3.2.4 Select条目
3.2.5 Depend条目
3.2.6 Comment条目
3.2.7 Source条目
3.2 Kconfig,Makefile和.config文件三者的关系
4.Linux内核配置选项
4.1 菜单形式的配置界面操作方法
4.2 配置界面主菜单类别
4.3 “System Type”菜单:系统类型
4.4 “Device Drivers”菜单:设备驱动程序
5.Kernel裁剪方法
参考文献:
1. 内核简介
1.1 内核版本及特点
Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,如图所示构成了linux的版本号:
其中的"VERSION","PATCHLEVEL"组成主版本号,比如5.3、5.4等。稳定的版本的主版本号用偶数表示(比如:5.2、5.4),每隔2~3年出现一个稳定版本。开发中的版本号用奇数来表示(比如5.1、5.3),他是下一个稳定版本的前身。
"SUBLEVL"称为次版本号,他不分奇偶,顺序递增。每隔1~2个月发布一个稳定版本。
"EXTRAVERSION"称为扩展版本号,他不分奇偶,顺序递增。每周发布几次扩展版本号,修正最新的稳定版本的问题。
1.2 获取内核源码
登陆Linux内核的官方网站www.kernel.org 可以看到如图所示内容:
上面标记了Linux内核的最新稳定版本、正在开发的测试版本。一般而言,各种补丁文件都是基于内核的某个正式版本生成的。使用内核补丁时,直接打补丁即可,补丁是迭代更新的。
1.3 内核启动过程简述
在裁剪内核之前,先了解他的启动过程。Linux的启动过程可以分为两部分:架构/开发板相关的引导流程,后续的通用启动流程。
1.3.1 内核引导阶段
内核映像被加载到内存并获得控制权之后,内核启动流程开始。通常,内核映像以压缩形式存储,并不是一个可以执行的内核。因此,内核阶段的首要工作是自解压内核映像。内核编译生成vmliunx后,通常会对其进行压缩,得到zImage(小内核,小于512KB)或bzImage(大内核,大于512KB)。在它们的头部嵌有解压缩程序。引导阶段通常使用汇编语言编写,他首先检查内核是是否支持当前架构的处理器,然后检查是否支持当前开发板。通过检查后,就为调用下一阶段的start_kernel函数作准备了,这主要分如下两个步骤:
① 连接内核时使用的虚拟地址,所以要设置页表、使能MMU。
② 调用C函数start_kernel之前的常规工作,包括复制数据段、清除BBS段、调用start_kernel函数。内核引导阶段如图所示:
1.3.2 内核初始化阶段
第二阶段的关键代码主要使用C语言编写。他进行内核初始化的全部工作,最后调用rest_init函数启动init过程,创建系统第一个进程:init进程。在这一阶段,仍有部分架构、开发板相关的代码。函数所在的位置:kernel/init/Main.c。内核初始化阶段的流程图如图所示:
2. 内核源码结构及Makefile分析
Linux内核庞大,但是这些文件的结构还是有章可循的,分别位于不同的目录下,各个目录功能相对独力。
目录名 |
描述 |
Arch |
体系结构相关的代码,对于每个架构的CPU,arch目录下有一个对应的子目录,比如arch/arm、arch/i386 |
Block |
块设备的通用函数 |
Crypto |
常用加密和散列算法,还有一些压缩的CRC校验算法 |
Drivers |
所有的设备驱动程序,里边每一个子目录对应一类驱动程序 |
Fs |
Linux支持的文件系统代码,每一个子目录对应一种文件系统 |
Include |
内核头文件,有基本文件(存放在include/linux/目录下)、各种驱动或功能部件的头文件(比如include/media、include/mtd、include/net)、各种体系相关的头文件(比如include/asm-arm/)。当配置内核后,include/asm是某个include/asm-xxx/(比如include/asm-arm/)的链接 |
Init |
内核的初始化代码(不是系统的引导代码),其中的main.c文件中的start_kernel函数是内核引导后运行的第一个函数 |
Ipc |
进程间通信的代码 |
Kernel |
内核管理的核心代码,与处理器相关的代码位于arch/*/kernel/目录下 |
Lib |
内核用到的一些库函数代码,比如crc32.c、string.c,与处理器相关的库函数代码位于arch/*/lib目录下 |
Mm |
内存管理代码,与处理器相关的内存管理代码位于arch/*/mm/目录下 |
Net |
网络支持代码,每个子目录对应于网络的一个方面 |
Security |
安全、秘钥相关的代码 |
Sound |
音频设备的驱动程序 |
Usr |
用来制作一个压缩的cpio归档文件;initrd的镜像,他可以作为内核启动后挂接(mount)的第一个文件系统 |
Documentation |
内核文档 |
Scripts |
用于配置,编译内核的脚本文件 |
2.1 Linux内核Makefile分析
内核中的那些文件将被编译?他们是怎么被编译的?他们的连接顺序如何确定?哪个文件在最前边?那些文件或者函数先执行?这些都是通过Makefile来管理的。从最简单的角度总结Makefile的作用,有以下3点:
1)决定编译哪些文件
2)怎样编译这些文件
3)怎样连接这些文件,最重要的是他们的顺序如何?
Linux内核源码中含有很多个Makefile文件,这些Makefile文件又要包含其他一些文件。这些文件构成了linux的Makefile体系,可以分为表中的5类。
名称 |
描述 |
顶层Makefile |
它是所有Makefile文件的核心,从总体上控制着内核的编译,连接 |
.config |
配置文件,在配置内核时生成。所有Makefile文件(包括顶层目录及各级子目录)都是根据.config来决定使用哪些文件 |
Arch/$(ARCH)/Makefile |
对应体系结构的Makefile,他用来决定哪些体系结构相关的文件参与与内核的生成,并提供一些规则来生成特定的内核映像 |
Scripts/Makefile* |
Makefile共用的通用规则、脚本等 |
Kbuild/Makefile |
各级子目录下的Makefile,他们相对简单,被上一层Makefile调用来编译当前目录下的文件 |
内核文档中Documentation/kbuild/makefiles.rst对Makefile有一定的讲解。以下根据前边总结的Makefile的三大作用分析这5类文件。
2.1.1决定编译那些文件
Linux内核的编译过程从顶层Makefile开始,然后递归地进入各级子目录调用他们的Makefile,分为三个步骤。
1)顶层Makefile决定内核根目录下哪些子目录将被编进内核。
2)Arch/$(ARCH)/Makefile决定Arch/$(ARCH)目录下哪些文件、哪些目录将被编进内核。
3)各级子目录下的Makefile决定所在目录下哪些文件将被编进内核,哪些文件将被编进模块(即驱动程序),进入哪些子目录继续调用他们的Makefile。
在顶层Makefile中,可以看到如图所示:
可见,顶层Makefile将这9个子目录分为7类:init-y.drivers-y,drivers-$(CONFIG_SAMPLES),net-y,libs-y,core-y,virt-y。除去include目录和后边两个不包含内核代码的目录外,还有一个arch目录没有出现在内核中。他在arch/$(ARCH)/Makefile中被包含进内核,在顶层Makefile中直接包含了这个Makefile,如下图2-2所示:
对于SRCARCH变量,可以在执行make命令时传入。比如“make SRCARCH=…”。
对于步骤2)的arch/$(ARCH)/Makefile,在arch/arm/Makefile中可以看见如下内容:
head-y := arch/arm/kernel/head$(MMUEXT).o
除了前边的7类子目录意外,又出现了另一类:head-y,不过他直接以文件名出现。
如图所示,第297行,扩展了libs-y的内容,这些都是体系结构相关的目录。上图中$(…)在配置内核时定义,他的值有三种:
Y:表示编进内核
M:表示编为模块
空:表示不使用
编译内核时,将依次进入:init-y,core-y,libs-y.drivers-y和net-y所列出的目录中执行他们的Makefile,每一个目录都会生成一个built-in.o(libs-y所列目录下,有可能生成lib.a文件)。最后,head-y所表示的文件将和这些built-in.o、lib.a一起被连接成内核映像文件vmlinux。
对于步骤3)在配置内核时,生成配置文件.config(具体的配置过程在下文的config分析中讲述)。内核顶层Makefile间接包含.config文件,以后就根据.config中定义的各个变量决定编译哪些文件。之所以说是间接包含,是因为包含的是include/config/auto.conf文件,而他只是将.config文件中的注释去掉,并根据顶层Makefile中定义的变量增加了一些变量而已。如图所示:
在include/config/auto.conf文件中,变量的值主要有两类:“y”和“m”。各级子目录的Makefile使用这些变量来决定哪些文件被编进内核中,哪些文件被编成模块(即驱动程序),要进入哪些下一级子目录继续编译,这要通过以下四种方法来确定:
Obj-y用来定义哪些文件被编进(built-in)内核
Obj-y中定义的.o文件由当前目录下的.c或.s文件编译生成,他们连同下级子目录的built.o文件被组合成(使用“$(LD)-r”命令)当前目录下的built-in.o文件,这个built-in.o被上一层的Makefile文件使用。
Obj-y中各个.o文件的顺序是有意义的,因为内核中使用moduel_init()或initcall定义的函数将按照他们的连接顺序被调用。
Obi-m用来定义那些文件被编译成可加载模块
Obj-m中定义的.o文件由当前目录下的.c或.s文件编译生成,他们不会被编译进built-in.o中,而是被编成可加载模块。
一个模块可以由一个或几个.o文件组成。对于只有一个源文件的模块,在obj-m中直接增加他的.o文件即可。对于有多个源文件的模块,除了在obj-m中增加一个.o文件外,还要定义一个<modem_name>-objs变量来告诉Makefile这个.o文件由哪些文件组成。
例:当下边的CONFIG_ISDN在.config文件中被定义为m时,将会生成一个isdn.o文件,他由isdn-objs中定义的…三个文件组合,而isdn.o最后被知错成isdn.ko模块。
Obj-$(CONFIG_ISDN) += isdn.o
Isdn-objs F isdn_net_lib.o isdn_v110.o isdn_commom.o
就这样,本应该被编译成isdn_net_lib.o isdn_v110.o isdn_commom.o的isdn_net_lib.c isdn_v110.c isdn_commom.c文件,被编译成了isdn.o文件。
Lib-y用来定义那些文件被编译成库文件。Lib-y定义的.o文件由当前目录下的.c或.s文件编译生成,他们被打包成当前目录下的一个库文件lib.a,同时出现在obj-y、lib-y中的.o文件不会被包含进lib.a中。要把这两个lib,a编进内核中,需要在顶层Makefile中libs-y变量中列出当前目录,要编成库文件的内核代码一般都在这两个目录下:lib/、arch/$(ARCH)/lib/。Obj-y、obj-m还可以用来指定要进入的下一层子目录
Linux中的一个Makefile文件只负责生成当前目录下的目标文件,子目录下的目标文件由子目录下的Makefile生成。Linux的编译系统会自动进入这些子目录调用他们的Makefile,知识在这之前需要制定这些子目录。这就要用到obj-y、obj-m,只要在其中增加这些子目录名即可。
例:obj-$(CONFIG_JFFS2_FS) +=jffs2/
2.1.2 怎样编译这些文件
即编译选项、连接选项是什么。这些选项分为三类:全局的,适用于整个内核代码树;局部的,仅适应于某个Makefile中的所有文件;个体的,仅适用于某个文件。全局选项在顶层Makefile和arch/$(ARCH)/Makefile中定义,这些选项的名称是:CFLAGS、AFLAGS、LDFLAGS、ARFLAGS,他们分别是编译C文件的选项,编译汇编文件的选项,连接文件的选项,制作库文件的选项。需要使用局部选项时,他们在各个子目录中定义,名称为EXTRA_CFLAGS、…、用途和上边的相同,只针对当前Makefile中的所有文件。个体编译:可以使用CFLAGS_$@...。$@表示某个文件目标文件名,例:CFLAGS_aha152x.0
2.1.3 怎样链接这些文件
前边分析了有哪些文件需要编进内核,顶层Makefile和arch/$(ARCH)/Makefile定义了7类目录。在顶层目录中,这些目录名的后面直接加上built-in.o或者lib.a,表示要连接进内核的文件,如下图所示:
Patsubst是个字符串处理函数,用法如下:$(patsubse pattern,replacement,text)。表示寻找“text”中符合格式“pattern”的字,用“replacement”替换他们。比如上边的init-y初值为“init/”,经过交换后,“init-y”变成“init/built-in.o”。顶层Makefile中,再往下看。如图所示
表示alldirs构成内核映像文件vmlinux的目标文件,由上图可知,这些目标文件的顺序。对于ARM体系,连接脚本是arch/arm/kernel/vmlinux.lds,他由arch/arm/kernel/vmlinux.lds.S文件生成,规则在script/Makefile.build中。
下边对分析Makefile做一下总结:配置文件.config中定义了一系列的变量,Makefile将结合他们来决定哪些文件被编进内核,哪些文件被编成模块,涉及哪些子目录。顶层Makefile和arch/$(ARCH)/Makefie决定根目录下哪些子目录、arch/$(ARCH)目录下哪些文件和目录将被编进内核。最后,各级子目录下的Makefile决定所在目录下哪些文件将被编进内核,哪些温江将被编成模块,进入哪些子目录继续调用他们的Makefile。顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、连接选项:CFLAGS,AFLAGS,LDFLAGS,ARFLAGS.各级子目录下的Makefile中可以设置能够影响当前目录下所有文件的编译,连接选项。顶层Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)/kernel/vmlinux.lds生成内核映象文件。
3. Kconfig分析
在内核目录下执行"make menuconfig ARCH=arm"时,就会看到一个如图3.1所示的菜单,这就是内核的配置界面。通过配置界面,可以选择芯片类型,选择需要支持的文件系统,去除不需要的选项等,这就称为配置内核。也就其他形式的配置方式,比如"make config"命令启动字符配置界面。"make xconfig"命令启动X-windows图形配置界面。有兴趣可以尝试一下后两种方式。
所有的配置工具都是通过读取arch/$(ARCH)/Kconfig文件来生成配置界面,这个文件是所有配置文件的总入口,他会包含其他目录的Kconfig文件。
3.1 Kconfig文件的基本要素
3.1.1 Config条目
Config条目常备其他条目包含,用来生成菜单、进行多项选择等。Config条目用来配置一个选项,或者说,它用来生成一个变量,这个变量会连用他的值被写进.config文件中。举个例子:
选自fs/Kconfig文件,用于配置CONFIG_TMPFS_POSIX_ACL选项。第128行中,config是关键字,表示一个配置项的开始;TMPFS_POSIX_ACL是配置项的名称,省略了前缀“CONFIG_”。129行中,bool表示变量类型。一共有5中类型:bool,tristate,string,hex,int。Bool之后的字符串是提示信息。130行表示依赖关系,只有TMPFS配置选项被选中时,才能设置当前配置选。注意:如果依赖条件不满足,则他取默认值。131和132行表示,当TMPFS_POSIX_ACL被选中时,配置TMPFS_XATTR和FS_POSIX_ACL也会被自动选中。当一行的缩进距离比第一行帮助信息的缩进距离小时,表示帮助信息结束。
3.2.2 Menu条目
Menu条目用于生成菜单,格式如下:
“menu” <prompt>
<menu options>
<menu block>
<endmenu>
109行,Menu之后的字符串是菜单名,“menu”和“endmenu”之间有很多config条目,在配置界面会出现menu名称字样,移动光标选中它回车进入,就会看到这些config条目。
3.2.3 Choice条目
Choice条目将多个类似的选项组合在一起,供用户单选或多选。实际使用中,也是在“choice”和“endchoice”之间定义多个config条目,比如init/Kconfig中有如下代码。
第119行中,prompt “Kernel compression mode”给出提示消息“Kernel compression mode”,光标进入后,就能看到多个config条目定义的配置选项。Choice条目中,定义的变量类型只能有两种:bool和tristate,并且不能同时有着两种类型的变量。对于bool类型的choice条目,只能在多个选项中选择一个。对于tristate类型的chioce条目,要么就把多个(可以是一个)选项都设为m,要么就像bool类型的条目一样,只能选择一个。
3.2.4 Select条目
反向依赖关系,该选项选中时,同时选中select后面定义的那一项。
3.2.5 Depend条目
该选项依赖于另一个选项,只有当依赖项被选中时,当前配置项的提示信息才会出现,才能设置当前配置项。如图所示:
3.2.6 Comment条目
用于定义一些帮助信息,会显示在配置界面上,也会在.config中以注释的形式显示
3.2.7 Source条目
Source条目用于读取另一个Kconfig文件。
3.2 Kconfig,Makefile和.config文件三者的关系
简单来说就是去饭店点菜:Kconfig是菜单,Makefile是做法,.config就是你点的菜。
Makefile:一个文本形式的文件,编译源文件的方法。
Kconfig:一个文本形式的文件,内核的配置菜单。
.config:编译内核所依据的配置。
Linux 内核源码树的每个目录下都有两个文档Kconfig和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个 Kconfig分别描述了所属目录源文档相关的内核配置菜单。在执行内核配置make menuconfig时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文档中。在内核编译时,主Makefile调用这 个.config,就知道了用户的选择。这个内容说明了,Kconfig就是对应着内核的每级配置菜单。
1.Makefile
(1)直接编译
obj-y += xxx.o
表示由xxx.c或xxx.s编译得到xxx.o并直接编进内核。
(2)条件编译
obj -$(CONFIG_HELLO) += xxx.o
根据.config文件的CONFIG_XXX来决定文件是否编进内核。
(3)模块编译
obj-m +=xxx.o
表示xxx作为模块编译,即执行make modules时才会被编译。
2、Kconfig
每个config菜单项都有类型定义: bool布尔类型、 tristate三态(内建、模块、移除)、string字符串、 hex十六进制、integer整型。
作用:决定make menuconfig时展示的菜单项
3、.config
通过前俩个文件的分析,.config的含义已经很清晰:内核编译参考文件,查看里面内容可以知道哪些驱动被编译进内核。
配置内核方式有3种(任选其一):
(1)make menuconfig
(2)make xxx_defconfig
(3)直接修改.config
注意: 如果直接修改.config,不一定会生效,因为有些配置可能存在依赖关系,make时会根据依赖关系,进行规则的检查,直接修改.config有时无效,所以不推荐直接修改。
4.Linux内核配置选项
4.1 菜单形式的配置界面操作方法
在源码目录下执行make menuconfig ARCH=arm进入内核配置界面,如图所示:
最上边一行,就是一些简单操作的方法。
4.2 配置界面主菜单类别
表中讲解了主菜单的类别,可以根据自己所要设置的功能进入某个菜单,然后根据其中各个选项的帮助信息进行配置。
配置界面主菜单 |
描述 |
Code maturity level options |
代码成熟度选项:用于包含一些正在开发或者不成熟的代码、驱动程序。 |
General setup |
常规设置:比如增加附加的内核版本号、支持内存页交换功能、System V进程间通信等。 |
Loadable module support |
可加载模块支持:一般都会打开Enable loadable module support、Module unloading、Automatic kernel module loading |
Block layer |
块设备层:用于设置块设备的一些总体参数,比如是否支持大于2TB的块设备、是否支持大于2TB的文件、设置I/O调度器等。 |
System Type |
系统类型:选择CPU的架构、开发板类型等于开发板相关的配置选项 |
Bus support |
PCMCIA/CardBus总线支持 |
Kernel Features |
用于设置内核的一些参数,比如是否支持内核抢占、是否支持动态修改系统时钟等。 |
Boot options |
启动参数:比如设置默认的命令行参数等 |
Floating point emulation |
浮点运算仿真功能:目前Linux还不支持硬件浮点运算,所以要选择一个浮点仿真器。 |
Networking |
网络协议选项:一般都选择"Networking support"以支持网络功能,选择"Packet socket"以支持socket接口功能,选择"TCP/IP networking"以支持TCP/IP网络协议。通常可以选择"Networking support"后,使用默认设置 |
Device Drivers |
设备驱动程序:几乎包含Linux的所有的驱动程序 |
File system |
文件系统:可以在里边选择要支持的文件系统,比如EXT2、EXT3等 |
Profiling hacking |
调试内核时的各种选项 |
Security options |
安全选项:一般使用默认设置 |
Cryptographic options |
加密选项 |
Library routinus |
库子程序:比如CRC32检验函数、zlib压缩函数等 |
4.3 “System Type”菜单:系统类型
对于arm平台(在顶层Makefile中修改"ARCH"=arm),执行"make menuconfig"后,或者执行"make menuconfig ARCH=arm"后在配置界面可以看到"System Type"字样,进入他的另一个界面,如图所示:
进入System Type会得到另一个界面,如图所示:
进入ARM system type用来选择体系结构,进入之后选择Qualcomm MSM,如图所示:
查看帮助信息可以知道它对应的是:CONFIG_ARCH_QCOM,如图所示:
4.4 “Device Drivers”菜单:设备驱动程序
执行"make menuconfig ARCH=arm"后在配置界面可以看到"Device Drivers"界面,如图所示:
图中的各个子菜单和内核源码drivers/目录下各个子目录一一对应.如表所示。在配置过程中可以参考这个表格找到对应的配置选项:在添加新驱动时,也可以参考它来决定代码放在哪个目录下。表中的各个子菜单与内核源码drivers/目录下的各个子目录一一对应,如表所示:
Devices Drivers子菜单 |
描述 |
Generic Drivers Options |
对应drivers/base/目录,这是设备驱动程序中一些基本和通用的配置选项 |
Memory Technology Device |
对应drivers/mtd目录,用于支持各种存储设备,比如NOR flash,NAND flash等 |
Parallel port support |
对应drivers/parport目录,他用于支持各种并口设备,在一般的嵌入式开发板中用不到 |
Plug and play support |
对应drivers/pnp目录,支持各种即插即用的设备 |
Block devices |
对应devices/block目录,包括各种回环设备、RAMDISK等的驱动 |
ATA/ATAPI/RLL support |
对应drivers/ide目录,它用来支持ATA/ATAPI/MFM/RLL接口的硬盘,软盘,光盘等 |
SCSI device support |
对应device/scsi/目录,支持各种SCSI接口的设备 |
Serial ATA and paraller ATA |
对应devices/ata目录,支持SATA与PATA设备 |
Multi-device support |
对应devices/md目录,表示多设备支持(RAID和LVM)。RAID和LVM的功能是使多个物理设备组建成一个单独的逻辑磁盘 |
Network device support |
对应devices/net目录,用来支持各种网络设备,比如CS8900、DM9000等 |
ISDN subsysten |
对应drivers/isdn目录,用来提供总和业务数字网的驱动程序 |
Input device support |
对应devices/input目录,支持各类输入设备,比如键盘、鼠标等 |
Character devices |
对应drivers/char目录,他包含各种字符设备的驱动程序。串口的配置选项也是从这个菜单调用的,但是串口的代码在drivers/serial目录下 |
I2C support |
对应devices/i2c目录,支持各类I2C设备 |
SPI support |
对应devices/spi目录,支持各类SPI设备 |
Dallas's 1-wire bus |
对应devices/w1目录,支持一线总线 |
Hardware Monitoring support |
对应devices/hwmon目录。当前主板大多数都有一个监控硬盘健康的设备用于监视温度/电压/风扇转速等,这些功能需要I2C支持,在嵌入式开发板中一般用不到 |
Misc devices |
对应devices/misc目录,用于支持一些不好分类的设备,称为杂项设备 |
Multifunction device drivers |
对应devices/mfs目录,用来支持多功能的设备 |
LED devices |
对应devices/led目录,包含各种led驱动程序 |
Multimedia devices |
对应devices/media目录,包含多媒体驱动,他用于向上统一的图像、声音接口 |
Graphice support |
对应drivers/video目录,提供图形设备/显卡的支持 |
Sound |
对应sound/目录(他不在devices/目录下),用来支持各种声卡 |
HID devices |
对应drivers/hid目录,用来支持各种USB-HID设备,或者符合USB-HID规范的设备(比如蓝牙设备)。HID表示human interface device,比如各种USB接口的鼠标/键盘/游戏杆/手写板等输入设备 |
USB support |
对应devices/usb目录,包括各种USB Host和USB Devices设备 |
MMN/SD card support |
对应drivers/mmc目录,用来支持各种MMC/SD卡 |
Real Time Clock |
对应drivers/rtc目录,用来支持各种实时时钟设备 |
5.Kernel裁剪方法
前边已经讲了Kconfig、.config、Makefile和make menuconfig的关系,在这里便可以很轻易的知道.config文件的修改方法。在内核源码目录下执行make menuconfig ARCH=arm进入到内核配置界面后,根据自己的配置要求将不用的选项配置成n,保存退出配置界面,这时就会生成一个新的.config文件,与之前的.config文件进行对比(可以使用Beyond Compare进行对比),找出差异项。举个例子,在内核源码目录下执行make menuconfig ARCH=arm,将Device Drivers ---> PCI support ---> PCI Express Port Bus support置为不参与编译,如图所示。
将Device Drivers ---> PCI support ---> PCI Express Port Bus support修改之后保存退出配置界面,会生成对应的.config文件将之前的.config文件覆盖,对比现在和之前的.config文件,如图所示:
我们可以发现CONFIG_PCIEPORTBUS=y,CONFIG_PCIEAER=y,CONFIG_PCIEASPM=y,CONFIG_PCIEASPM_POWER_SUPERSAVE=y,CONFIG_PCIE_PME=y这5个配置选项被修改。
在源码下进入对应平台目录下,进入目录kernel/msm-5.4/arch/arm/configs/下,在配置文件中修改.config文件中的差异项,即可根据自己的配置要求配置出选项。某些差异项是在defconfig文件中找不到的,这就要用到其他方法来配置该配置选项。举个例子,如上的CONFIG_PCIEPORTBUS=y,将CONFIG_PCIEPORTBUS=y修改为CONFIG_PCIEPORTBUS=y is not set即可,如所示。再依次找到CONFIG_PCIEAER=y,CONFIG_PCIEASPM=y,CONFIG_PCIEASPM_POWER_SUPERSAVE=y,CONFIG_PCIE_PME=y,将他们分别修改为#CONFIG_XXXXXXX is not set即可,这样我们便是将Device Drivers ---> PCI support ---> PCI Express Port Bus support配置成不编译进入内核。
参考文献:
[1] 韦东山.嵌入式LINUX应用开发完全手册.人民邮电出版社
[2] 陈皓.跟我一起学makefile
[3] [J/OL] .Linux内核架构及内核裁剪.https://blog.csdn.net/u012516571/article/details/79649828
[4][J/OL]. linux内核裁剪的具体过程和方法.https://blog.csdn.net/u011124985/article/details/80453772文章来源:https://www.toymoban.com/news/detail-757145.html
[5][J/OL]. linux4.10.8 内核移植(三).https://www.cnblogs.com/kele-dad/p/7107544.html文章来源地址https://www.toymoban.com/news/detail-757145.html
到了这里,关于【Linux Kernel】Linux内核裁剪的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!