linux内核配置相关知识

1. 相关配置文件的作用
在进行 linux 内核的配置编译的时候,最常见的就是 make menuconfig 命令。总所周知,linux是一个模块化定制的系统,那么它又是如何来实现模块化的配置的呢?

在配置的过程中,我们最重要的就是理清楚 kconfig、.config 、 menuconfig之间的关系。

在Linux内核中,添加驱动代码一般有3部:

将代码拷贝到Linux内核代码恰当的地方

新建或者修改对应的kconfig文件

新建或修改对应的makefile文件
 

Kconfig ---> (每个源码目录下)提供编译选项
.config ---> (源码顶层目录下)保存选择结果
Makefile---> (每个源码目录下)根据.config中的内容来告知编译系统如何编译

1.1 deconfig 文件
一般由平台厂商提供,内核编译用做 .config 的参考,注意:如果,缺少该文件,无法进行编译。

文件位于:\kernel..\arch\arm\configs\xxx_defconfig

1.2 .config 文件
默认情况下是没有 .config 文件的,配置过程就是为了产生 .config 文件。内核在编译过程中会读取 .config 中的配置项,并且用这些配置项去指导整个编译链接过程。.config 文件的格式类似于脚本文件,其中内容为类似于:CONFIG_ARM=y 的一个一个的配置项。这些配置项就类似于脚本文件中定义的一个一个变量,所以这一行可以被理解为定义了一个变量 CONFIG_ARM,这个变量的值为 y。.config文件中每一行都是一个配置项,从 .config 文件的规模可以看出linux内核的可配置项有两三千个。所以linux内核是高度可配置的,而且linux内核的所有配置项很难全部搞明白。因为linux内核的配置项太多太繁杂,因此linux内核不像uboot那样直接手工配置,而是发明了一个图形化的配置工具 menuconfig。

.config 文件是一个隐藏文件,要用 “ls -a” 才能看见,默认是没有这个文件的,需要执行配置命令(make xxxx_defconfig)后才会生成。.config文件最初就是由xxxx_defconfig文件复制得来,里面全是配置项,以行为单位。每个配置项的格式都是CONFIG_xxx=x,每个配置项都可以在menuconfig中找到。CONFIG_xxx是配置项的名字,该配置项在menuconfig中的名字就是xxx,等号后面是配置的结果,可以是Y、N、M,Y代表编译连接此模块,N代表不编译此模块,M代表将该模块单独编译成.ko文件。

总结:.config文件最初由xxxx_defconfig文件复制得来,然后可以在menuconfig中做修改,最终Makefile会读取.config文件,里面的每个配置项都会指导内核的编译。

1.3 kconfig
kconfig 是一种特定格式的脚本文件,分布在各目录下的 Kconfig 构成了一个分布式的内核配置数据库,每个 Kconfig 分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等) 时,从 Kconfig 中读出配置菜单,用户配置完后保存到 .config (在顶层目录下生成)中,供 Makefile 文件在编译内核时使用。

kconfig脚本的格式如下图所示:

1.4 makefile
分布在各个目录下,用于集成编译。

defconfig、 .config 、kconfig 与makefile的用途与关系

defconfig、 .config 、kconfig 与makefile和make menuconfig流程

2. 内核中修改和保存defconfig的方法
从.config到defcong不是简单的复制操作,而是make arch=arm64 defcong

通过menuconfig生成的.confg也不是直接拷贝成defcong,而是使用make savedefconfig,具体步骤如下:

要修改在 arch/arm/configs 下的文件 xxx_defconfig

B
make xxx_defconfig 会生成 .config 文件。

C
make menuconfig 修改配置后保存。

D
make savedefconfig 生成 defconfig 文件。

F
cp defconfig arch/arm/configs/xxx_defconfig 保存这样保存的 defconfig 文件,配置最小化

要修改在 arch/arm/configs 下的文件 xxx_defconfig
make xxx_defconfig 会生成 .config 文件。
make menuconfig 修改配置后保存。
make savedefconfig 生成 defconfig 文件。
cp defconfig arch/arm/configs/xxx_defconfig 保存这样保存的 defconfig 文件,配置最小化

3. 常用配置命令解释

config 使用基于行的程序更新当前配置
nconfig 使用ncurses基于菜单的程序更新当前配置
menuconfig 使用基于菜单的程序更新当前配置
xconfig 使用基于Qt的前端更新当前配置
gconfig 使用基于GTK +的前端更新当前配置
oldconfig 使用提供的.config作为基础更新当前配置
localmodconfig 更新当前配置禁用未加载的模块
localyesconfig 更新当前配置,将本地mod转换到内核
defconfig 默认来自Arch提供的defconfig的新配置
savedefconfig 将当前配置保存为./defconfig(最小配置) 
allnoconfig 新配置,其中所有选项均以“否”回答
allyesconfig 新配置,其中所有选项都被'yes'接受
allmodconfig 尽可能新配置选择模块
alldefconfig 新配置,所有符号都设置为默认值
randconfig 新配置,随机回答所有选项
listnewconfig 列出新选项
olddefconfig 与oldconfig相同,但在没有提示的情况下将新符号设置为其默认值
kvmconfig 为KVM虚拟机内核支持启用其他选项
xenconfig 为xen dom0和虚拟机内核支持启用其他选项
tinyconfig 配置最小的内核

make config
基于命令行的,文本式的,交互式的,对话式的,配置。—不太方便使用。

make menuconfig
基于菜单式的,属于带图形界面的,或者叫辅助图形界面,基于ncurses库。—方便使用

make xconfig
真正的,图形界面的配置,用到的是QT的库。但是个人觉得界面效果也不是很好。
加上由于用到额外的图形库,所以用起来也不是那么的广泛。

make gconfig
也是图形界面。用到的是GTK的库。

make defconfig
调用默认的配置。
其和上面三个:make config,make menuconfig,make xconfig,不是一伙的。
其不是另外一种配置的方式。而是(直接去)使用某个默认的配置,即和配置内容相关。和使用何种配置方式(命令行,还是图形界面等等)无关。

make oldconfig
其使用old,旧的配置。

4 常用的3种配置方法

1:make menuconfig(从头到尾每一项一个一个配置,成千上万个配置项要配置,很复杂,不可取)

2:使用默认的配置,在此基础上修改。

1)但现在不知道默认的配置有哪些。可以搜索下:find –name *_defconfig *

2)在/arch/arm目录下找,找和我们的单板相似的架构配置xxx_defconfig。make xxx_defconfig.以其作为默认配置,执行完 make xxx_defconfig 后,显示“配置文件”写到了 ".config" 文件中。

3)再make menuconfig,用菜单继续完成自己所需的配置,会先去读.config文件,在此基础上继续配置。

3:使用厂家提供的配置文件。将厂家提供config直接复制一份为 .config,或者执行make xxx_defconfig.c生成相应开发板厂家提供的默认配置文件.config文件(或者将它改成 .config),然后make menuconfig继续配置。

5 符号表示

[*]:表示选取了该选项,编译好后的kernel就会有该功能

[ ]:表示未选取该项,编译后的kernel不会有此功能

[M]:表示选取了该选项,而且是编译成模块module的形式,它会在kernel被载入后被动态地加载,编译成module可以减少kernel image的空间,加快开机速度,方便以后修改

< >:表示未选取该项,但是该功能被当做module,今后可以在开机后另外载入

前面没有中括号的表示系统默认选中,不能配置.

.config”中的配置值(=y、=m、没有)会影响最终的编译链接过程。如果=y则会被编入(built-in),如果=m会被单独连接成一个”.ko”模块,=n则对应的代码不会被编译。通过makefile实现的。

 6 Kconfig语法

Kcofnig 文件中 的 depends 和 select

 depends:意思是本配置项依赖于另一个配置项。如果那个依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的那个配置项本身被设置为N,则本配置项根本没有意义。depends项会导致make menuconfig的时候找不到一些配置项。所以在menuconfig中如果找不到一个选项,但是这个选项在Kconfig中却是有的,则可能的原因就是这个配置项依赖的一个配置项是不成立的。depends依赖的配置项可以是多个,还可以有逻辑运算。这种时候只要依赖项目运算式子的结果为真则依赖就成立。

select : “select”表示方向依赖,当选中“ARC”以后,“HAVE_PRIVATE_LIBGCC”、“HAVE_GENERIC_BOARD”、“SYS_GENERIC_BOARD”和“SUPPORT_OF_CONTROL”这四个也会被选中。

Kconfig文件内容与menuconfig的条目有对应关系。

source

和makefile一样,Kconfig也可以调用其他子目录中的Kconfig文件,调用方法如下:

    source    "xxx/Kconfig"    //xxx为具体的目录名,相对路径

menu/endmenu条目

menu用于生成菜单,endmenu就是菜单结束标志,这两个一般是成对出现的。

config条目

在menu/endmenu代码块中有大量的“config  xxxx”的代码块,也就是config条目。config条目就是“General setup”菜单的具体配置项

choice/endchoice

choice/endchoice代码段定义了一组可选择项,将多个类似的配置项组合在一起,供用户单选或者多选。

7 内核配置查找示例

 Symbol: USB [=y] │   表示xxx已经配置为y

│ Type : tristate │  表示三态(y,M,n) boolean表示二态(y,n)
│ Defined at drivers/usb/Kconfig:44 │
│ Prompt: Support for Host-side USB │ 后边的字符串就是最终要配置的项  //对应Kconfig的tristate后边的字符串
│ Depends on: USB_SUPPORT [=y] && USB_ARCH_HAS_HCD [=y] │  依赖的配置 如果后面有多个选项择其中至少一个被选择,这个选项才能被选
│ Location: │ 该项配置所在的路径
│ -> Device Drivers │
│ (1) -> USB support (USB_SUPPORT [=y]) │
│ Selects: GENERIC_ALLOCATOR [=y] && USB_COMMON [=y] && NLS [=y] │   本项的选择所影响的选择
│ Selected by [n]: │  本项自己不能选择,只能被这个字符串中的内容来选择。
│ - MOUSE_APPLETOUCH [=n] && INPUT [=y] && INPUT_MOUSE [=y] && USB_ARCH_HAS_HCD [=y] │
│ - MOUSE_BCM5974 [=n] && INPUT [=y] && INPUT_MOUSE [=y] && USB_ARCH_HAS_HCD [=y] │
│ - MOUSE_SYNAPTICS_USB [=n] && INPUT [=y] && INPUT_MOUSE [=y] && USB_ARCH_HAS_HCD [=y] │
│ - JOYSTICK_XPAD [=n] && INPUT [=y] && INPUT_JOYSTICK [=n] && USB_ARCH_HAS_HCD [=y] │
│ - JOYSTICK_PXRC [=n] && INPUT [=y] && INPUT_JOYSTICK [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TABLET_USB_ACECAD [=n] && INPUT [=y] && INPUT_TABLET [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TABLET_USB_AIPTEK [=n] && INPUT [=y] && INPUT_TABLET [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TABLET_USB_HANWANG [=n] && INPUT [=y] && INPUT_TABLET [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TABLET_USB_KBTAB [=n] && INPUT [=y] && INPUT_TABLET [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TABLET_USB_PEGASUS [=n] && INPUT [=y] && INPUT_TABLET [=n] && USB_ARCH_HAS_HCD [=y] │
│ - TOUCHSCREEN_USB_COMPOSITE [=n] && INPUT [=y] && INPUT_TOUCHSCREEN [=y] && USB_ARCH_HAS_HCD [=y] │
│ - INPUT_ATI_REMOTE2 [=n] && INPUT [=y] && INPUT_MISC [=y] && USB_ARCH_HAS_HCD [=y] │
│ - INPUT_KEYSPAN_REMOTE [=n] && INPUT [=y] && INPUT_MISC [=y] && USB_ARCH_HAS_HCD [=y] │
│ - INPUT_POWERMATE [=n] && INPUT [=y] && INPUT_MISC [=y] && USB_ARCH_HAS_HCD [=y] │
│ - INPUT_YEALINK [=n] && INPUT [=y] && INPUT_MISC [=y] && USB_ARCH_HAS_HCD [=y] │
│ - INPUT_CM109 [=n] && INPUT [=y] && INPUT_MISC [=y] && USB_ARCH_HAS_HCD [=y] │
│ - USB_PULSE8_CEC [=n] && MEDIA_CEC_SUPPORT [=y] && USB_SUPPORT [=y] && TTY [=y] │
│ - USB_RAINSHADOW_CEC [=n] && MEDIA_CEC_SUPPORT [=y] && USB_SUPPORT [=y] && TTY [=y]

make menuconfig的最后一步,会有提示,比如缺少了某个depends on,此时按下"Esc",然后按"h",即可查看Depends on。

例:有的模块取决于另一模块,若另一模块配置为M,则本模块也得配置为M

menu和choice的区别

menu 可以多选 choice 是单项选择题

posted @ 2023-12-04 16:32  okyihu  阅读(53)  评论(0编辑  收藏  举报