在内核源数目录下一般会存在两个文件,一个是Makefile文件,另一个是Kconfig文件。那.config文件呢?其实它是一个中间产物,在make menuconfig后会生成此文件,这个menuconfig这个选项其实就是Kconfig文件中编写的,而Makefile就是告诉编译器如何编译,如何生成我们想要的模块或者结果。
三者的大致顺序关系:
我们现在拿个实例来分析:
Kconfig文件我们来cat一下:
config SCSI_UFS_CRYPTO_QTI
tristate " specific UFS Crypto Engine Support"
depends on SCSI_UFS_CRYPTO
help
Enable Support in UFS
Enabling this allows kernel to use UFS crypto operations defined
and implemented by QTI.
source "driver/vfio/pci/Kconfig”
我们从上面的信息中我们可以看出来文件名称,用途,依赖模块,帮助信息等等,当然,这个信息不是概括的特别全面,我们在shell下输入make menuconfig的时候就可以看到SCSI_UFS_CRYPTO_QTI这个选项了,输入y表示编译内核;输入n表示不编译;输入m表示模块编写。
在tristate部分,属于option,还有其他的可以选择:
bool:布尔类型, tristate三态:内建、模块、移除, string:字符串, hex:十六进制, integer:整型
例子1:
config hello
bool "hello test module"
tristate类型的选项,假如选择编译成内核模块,则会在.config中生成一个CONFIG_HELLO=m的配置,假如选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_HELLO=y的配置。
例子2:
依赖型定义depends on或requires指此菜单的出现是否依赖于另一个定义
config HELLO_MODULE
bool "hello test module"
depends on ARCH_PXA
HELLO_MODULE这个菜单项,只有在选择了ARCH_PXA, 该菜单才可见(可配置)。
例子3: Kconfig目录层次迭代
在Kconfig中
source "driver/vfio/pci/Kconfig”
这样的语句用来嵌套子目录或者其他目录的Kconfig文件,这样的好处就是不同的目录各种管理自己的配置选项,而不用都写在同一个文件里面。
例子4:
帮助性定义,增加帮助用关键字help或—help—
help
Enable Support in UFS
Enabling this allows kernel to use UFS crypto operations defined
and implemented by QTI.
Makefile
我们来cat一下:
obj-$(CONFIG_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o
obj-$(CONFIG_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o
obj-$(CONFIG_UFS_QCOM) += ufs-qcom.o
obj-$(CONFIG_UFSHCD) += ufshcd-core.o
ufshcd-core-y := ufshcd.o
obj-$(CONFIG_UFSHCD_PCI) += ufshcd-pci.o
obj-$(CONFIG_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
obj-$(CONFIG_UFS_TEST) += ufs_test.o
obj-$(CONFIG_FOO) += foo/
obj-$(CONFIG_MEMORY_SYSFS) += memory.o
mi_memory-$(CONFIG_MEMORY) += memory_sysfs.o
mi_memory-$(CONFIG_MEMORY) += ufs_info.o
mi_memory-$(CONFIG_MEMORY) += dram_info.o
看到上面的一头雾水,我们把它拆出来分析:
如果是简单的一个模块编译:
obj-$(CONFIG_UFS_TEST) += ufs_test.o
这样写是没有问题的
如果我们编译的模块需要依赖多个源文件,比如这样:
obj-$(CONFIG_MEMORY_SYSFS) += memory.o
mi_memory-$(CONFIG_MEMORY) += memory_sysfs.o
mi_memory-$(CONFIG_MEMORY) += ufs_info.o
mi_memory-$(CONFIG_MEMORY) += dram_info.o
根据CONFIG_MEMORY的配置属性来决定是否生成memory.o,然后根据CONFIG_MEMORY_SYSFS属性来决定将memory.o模块编入内核还是作为模块。
如果CONFIG_MEMORY_SYSFS已经配置成y(编入内核),代码就可以这样写:
obj-y += memory.o
mi_memory-$(CONFIG_MEMORY) += memory_sysfs.o
mi_memory-$(CONFIG_MEMORY) += ufs_info.o
mi_memory-$(CONFIG_MEMORY) += dram_info.o
同样条件允许的情况下,也可这样写:
obj-y += memory.o
mi_memory-m += memory_sysfs.o
mi_memory-m += ufs_info.o
mi_memory-m += dram_info.o
需要理解一个原则:makefile只负责处理本目录中的编译关系,其他目录中的文件编译由其他目录的makefile负责,整个linux内核的makefile组成一个树状结构,对于上层makefile的子目录而言,只需要让kbuild知道它应该怎样进行递归地进入目录即可。
还有这样的语句:kbuild利用目录指定的方式来进行目录指定操作
obj-$(CONFIG_FOO) += foo/
当CONFIG_FOO被配置成y或者m时,kbuild就会进入到foo/目录中,但是需要注意的是,这个信息仅仅是告诉kbuild应该进入到哪个目录,而不对其目录中的编译做任何指导。
~bin/kernel/
下:~bin/kernel/
目录下Kconfig:config HELLO
tristate “HELL"
这样当make menuconfig时 ,将会出现 HELL选项,假如您选择了此项。该选择就会保存在.config文档中。
~bin/kernel/
Makefile文件:obj-$(CONFIG_HELLO ) +=hello.o
当您编译内核时,将会读取.config文档,当发现hello选项为yes 时,系统在调用~bin/kernel/
下的makefile 时,将会把hello.o 加入到内核中。
如果在~bin/kernel/
下创建一个文件夹HELLO,并在文件夹下添加hello.c该怎么添加Makefile和Kconfig呢?
在对宽范围的Makefile进行一个描述:
2.6内核的Makefile分为5个部分:
* 最顶层的Makefile(在编译之前可更改上面几行版本名字,这样生成的新内核就是特定的名字)
* 内核的.config配置文件
* 在arch/$(ARCH)目录下的体系结构相关的Makefile
* 在s目录下的Makefile.*文件,是一些Makefile的通用规则
* 各级目录下的大概约500个kbuild Makefile文件
顶层的Makefile文件读取.config文件的内容,并总体上负责build内核和模块,各级体系架构的
Makefile负责架构相关的信息。s目录下的Makefile文件包含了所有用来根据kbuild Makefile
构建内核所需要的定义和规则。