0


【Linux Kernel】Linux内核裁剪

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

[5][J/OL]. linux4.10.8 内核移植(三).https://www.cnblogs.com/kele-dad/p/7107544.html

标签: linux

本文转载自: https://blog.csdn.net/qq_42723832/article/details/131925964
版权归原作者 Cyril-LL 所有, 如有侵权,请联系我们删除。

“【Linux Kernel】Linux内核裁剪”的评论:

还没有评论