内核Kconfig 与 Makefile 文件分析
一.内核构造系统简介
内核是个复杂庞大的系统,对它进行配置、裁剪、编译原本非常地复杂和困难,但现在却只需要简单的两个命令:(1)make menuconfig ;(2)make uImage 就搞定了,原因是在其背后有一个设计精巧的内核构造系统帮助我们精确的完成了各项任务。内核构造系统最关键的组成元素就是各个目录下的Kconfig 文件和 Makefile文件,本节将对这两类文件进行介绍,以使大家了解内核构造系统的基本情况,从而能够修改它们,以完成向内核中添加功能组件的目的。
二. Kconfig 文件精解
* Kconfig 文件的作用是:
1.控制make menuconfig 时, 出现的配置选项;
2.根据用户配置界面的选择,将配置结果保存在.config 配置文件(该文件将提供给Makefile使用,用以决定要编译的内核组件以及如何编译)。
初始Kconfig文件是arch /arm/Kconfig ( Kconfig文件的语法和语义,详情可查阅内核源码中的Documentation /kbuild/kconfig-language.txt 文件 )
(一)Kconfig 文件的基本要素:config 条目(entry)
configYAFFS_FS
tristate " YAFFS2 file system support "
default y
depends onMTD_BLOCK
selectYAFFS_YAFFS1
selectYAFFS_YAFFS2
help
YAFFS2 , or Yet Another Flash Filing System , is a filing system
optimised for NAND Flash chips.
To compile the YAFFS2 File system support as a module, choose M here :the module will be called yaffs2.
Ifunsure , say N
上面的config 条目,各部分的含义是:
(1)YAFFS_FS为变量名,将在.config 中以CONFIG_YAFFS_FS=y 或 n 的形式出现,如图
(2)tristate 为出现在配置菜单中的文字,没有它,将使得用户不能在配置界面中显示并配置它,同时它也为变量取值的类型,可为y 、n 、m
(3)default :为变量默认值,可被用户设置值覆盖。
(4)depends on :表示该变量必须在MTD_BLOCK被设置的情况下才能进行设置,否则取值为n ,即使default为y
(注:原来我的.config 文件中出现的形式时#CONFIG_YAFFS_FS is not set ,所以一致后来在make menuconfig菜单中找不到YAFFS2 file system support的选项,就是因为这个原因,后来设置成CONFIG_YAFFS_FS=y还是没有YAFFS2 file system support的选项,因为没有理解depends on MTD_BLOCK ,后来理解了,再次到.config文件中设置了此选项,菜单中终于有了"YAFFS2 file system support"的选项)
(5)select :表示它将影响到变量YAFFS_FS,使得YAFFS_FS至少应该配置为y或m(如果它最终取值为y 或 m )
(6) help :中的文字将作为配置界面中的帮助信息。
附加说明:
*** 无depends on ,default 为y : 默认为y。 一般用于必须要设置的选项,此时不要设置prompt 。
*** 有depends on ,default 为y :所依赖的条目己设置,则默认为y ; 所依赖的条目未设置,则为n.
*** 有depends on ,default 为n :所依赖的条目己设置,则默认为n; 所依赖的条目未设置,则为n.
*** 无depends on ,default 为n :在为设置prompt的情况下,此选项想要被设置,需要由其他选项来select它。
二.Kconfig 中变量的取值类型
Kconfig 中变量取值类型总共有5种。其中做常见的是tristate 和 bool ,分别对应于make meuconfig 配置界面中< > 和 [ ]选项。
(1)tristate :可取y 、n 、m。
(2)bool (其为tristate的变体) :可取 y 、n
(3)string :取值为字符串,如:CONFIG_CMDLINE = "root =/dev/hdalro init = /bin/bash console =ttySAC0 "
(4)hex (其为string的变体):取值为十六进制数据,如:CONFIG_VECTORS_BASE =0xffff0000.
(5)int (其为string的变体):取值为十进制数据,如:CONFIG_SPLIT_PTLOCK_CPUS=4096
三.Kconfig 文件的要素:source
由于内核源代码中大多数目录下都有各自的Kconfig 文件,因此需要一种手段将所有的Kconfig 文件组织为一个整体。这就是source的功能,它用于引入另一个Kconfig文件,有点类似于C语言的#include 。
(举例:在内核的fs/Kconfig 中增加一行: source "fs/yaffs2/Kconfig" 就是如此)
续篇:.config 文件说明
make menuconfig 配置完成退出时,选择保存,则用户所做的选择将保存在内核源代码顶层目录文件中.config文件中。下面.config文件的片段显示内核配置者作了如下选择:将YAFFS_FS 、YAFFS_YAFFS1功能编译进uImage;不编译BFS_FS、EFS_FS、YAFFS_9BYTE_TAG功能;
续篇:Makefile 文件说明
下面是内核drivers/net/Makefile 文件的片段:
12 obj - $ (CONFIG_ATL1) += atl1/
13 obj - $ (CONFIG_GIANFAR) += gianfar_driver.o
14
15 gianfar_driver - objs : = gianfar.o \
16 gianfar_ethtool.o \
17 gianfar_mii.o \
18 gianfar_sysfs.o
26 obj - $ (CONFIG_PLIP) + = plip.o
它的含义是:
(1)第26行,如果.config文件中变量CONFIG_PLIP=y,那么将编译本目录下的plip.文件并将其功能集成进uImage ;如果.config文件中变量CONFIG_PLIP=m,那么将编译本目录下的plip.c文件生成模块plip.ko;否则,将不编译plip.c。
(2)第13~18行,如果config文件中变量CONFIG_GIANFAR=y,那么将编译本目录下的cgianfar.c、gianfar_ethtool.c、gianfar_mii.c、gianfar_sysfs.c文件并将其功能集成进uImage ;如果config文件中变量CONFIG_GIANFAR=m,那么将编译本目录下的cgianfar.c、gianfar_ethtool.c、gianfar_mii.c、gianfar_sysfs.c文件生成模块并将其功能集成进gianfar_driver.ko ;否则不编译cgianfar.c、gianfar_ethtool.c、gianfar_mii.c、gianfar_sysfs.c文件。
(3)第12行,如果.config 文件中变量CONFIG_ARL1=y,将递归进入本目录的子目录atl1,并将根据子目录下的Makefile文件内容决定改子目录如何进行编译;否则,将不进入本目录的子目录atl1进行编译。
例如:
下面是内核fs/Makefile 文件的片段:如图:
之后进入yaffs2子目录下的Makefile 看看:如图: