linux中kernel编译所涉及的Makefile,Kconfig,.config,kbuild makefiles文件

前言

在内核源数目录下一般会存在两个文件,一个是Makefile文件,另一个是Kconfig文件。那.config文件呢?其实它是一个中间产物,在make menuconfig后会生成此文件,这个menuconfig这个选项其实就是Kconfig文件中编写的,而Makefile就是告诉编译器如何编译,如何生成我们想要的模块或者结果。

关系:

  • Makefile:文本形式的文件,包含一些规则告诉make编译哪些文件以及怎样编译这些文件。
  • .config:文件是在进行内核配置的时候,经过配置后生成的内核编译参考文件。
  • Kconfig:文本形式的文件,其中主要作用是在内核配置时候,作为配置选项。
  • make:make是linux下的一个程序软件,makefile相当于针对make程序的配置文件,当我们执行make命令时,make将会在当前目录寻找Makefile文件,然后根据Makefile的配置对源文件进行编译。
  • kbuild makefiles : 每一个模块都是单独被编译然后再链接的,所以这一种kbiuld makefile几乎在每个模块中都存在.在这些模块文件(子目录)中,也可以使用Kbuild文件代替Makefile,当两者同时存在时,优先选择Kbuild文件进行编译工作,只是用户习惯性地使用Makefile来命名。

三者的大致顺序关系:

  • 我们编写了Kconfig—>进行make menuconfig---->生成.config----->编写Makefile---->按照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应该进入到哪个目录,而不对其目录中的编译做任何指导。

添加一个bsp源文件

  • 第一步:将hello.c文件添加到~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 加入到内核中。

添加一个bsp文件夹,并在文件夹内添加源文件

如果在~bin/kernel/下创建一个文件夹HELLO,并在文件夹下添加hello.c该怎么添加Makefile和Kconfig呢?

  • 通过上面的讲解,应该大家也能自己添加,那就是分别在本级的Makefile和Kconfig分别添加配置与编译的路径就可以,并在新建文件夹中创建自己的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

      构建内核所需要的定义和规则。

猜你喜欢

转载自blog.csdn.net/weixin_42271802/article/details/109459354