在内核编译中如何将各个目录树中的文件组织起来编译是一个很重要的问题,并且要根据用户配置来编译特有的内核。为了解决这个问题,内核使用两种文件,Makefie和Kconfig。分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文档相关的内核配置菜单,就是我们使用命令 make menuconfig(或者xconfig)后产生的配置菜单,此菜单包含多层,每个层次都是由各个目录中的Kconfig产生的。用户根据需求来选择如何编译内核,然后将配置结果保存到.config中,然后执行Makefile时就会根据.config的结果来实现内核的编译。
这个过程是由kbuild系统来完成的,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。内核编译系统或者说kbuild,是一种在编译内核时,可以对内核配置选项进行选择的机制。2.6内核树中已经更新了这种机制,新版本的kbuild 不仅高速而且备有更完善的文档。Kbuild机制完全依赖于源代码的层次结构。
二、Makefile文件
面对树状结构的内核源码目录,内核编译采用了各个子目录拥有自己目录相关的Makefile(被称为sub-Makefile或kbuild Makefile),内核编译依赖于各个子目录下的子makefile(sub-Makefile)文件,这些sub-Makefile定义了根据该子目录下的源码文件构建目标文件的规则,并且仅对该目录下的文件作适当的修改。顶层Makefile采用递归的方式调用位于init/, drivers/, sound/, net/, lib/ ,usr/等目录下的各个子目录中的 Makefile文件。在递归调用之前,kbuild首先要确定是否已经满足一些必要的条件,包括在必要时更新include/Linux/version.h文件,并设置符号链接include/asm,使之指向与目标体系结构相关的文件。例如,如果为PPC编译代码,则include/asm指向include/asm-ppc。kbuild还要对文件include/Linux/autoconf.h和include/Linux/config进行编译。之后,从根目录开始进行递归。
各个子Makefile文件比较简单,指出了该如何编译目标文件,例如/mm目录下的Makefile片段:
16 obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o
17 obj-$(CONFIG_BOUNCE) += bounce.o
18 obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
19 obj-$(CONFIG_HAS_DMA) += dmapool.o
20 obj-$(CONFIG_HUGETLBFS) += hugetlb.o
三、Kconfig文件
Kconfig的作用就是为了让用户配置内核,在Kconfig中定义了一些变量,用户通过设置变量的值来选择如何个性化自己的系统内核。定义的变量将在
每个菜单都有一个关键字标识,最常见的就是config
语法:
config
symbol是个新的标记的菜单项,options是在这个新的菜单项下的属性和选项
其中options部分有:
1、类型定义:
每个config菜单项都要有类型定义,bool布尔类型、 tristate三态:内建、模块、移除 string字符串、 hex十六进制、 integer整型
例如config HELLO_MODULE
bool “hello test module”
bool 类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,假如选择编译成内核模块,则会在.config中生成一个 CONFIG_HELLO_MODULE=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个 CONFIG_HELLO_MODULE=y的配置.
2、依赖型定义depends on或requires
指此菜单的出现和否依赖于另一个定义
config HELLO_MODULE
bool “hello test module”
depends on ARCH_PXA
这个例子表明HELLO_MODULE这个菜单项只对XScale处理器有效。
3、帮助性定义
只是增加帮助用关键字help或—help—