利用Linux内核编译输出信息构建内核源码树

在使用Source Insight阅读Linux内核代码时,总会遇到某些宏或函数找不到定义、找到多个定义的情况,这是因为添加入工程的文件缺失或冗余了。

Linux内核代码量大,复杂性高,其中重要的一个原因是Linux对硬件的兼容性高,因此有很多屏蔽硬件细节的接口和具体每个硬件的实现。然而最终操作系统总要在具体的硬件上运行,编译内核使用的配置文件可以从繁杂的代码树中挑选出需要的枝干。因此我们添加代码时,要借鉴配置文件对代码树进行合理修剪。

以DM8168为例,TI提供了基于2.6.37的内核代码树,与Linux官方代码几乎完全一致。开发板使用的默认配置是arch/arm/configs/ti8168_evm_defconfig文件,打开该文件看到的是许多类似于

    CONFIG_ARM=y
    CONFIG_ARCH_OMAP=y
    # CONFIG_SYSFS_DEPRECATED is not set
    CONFIG_INET_TUNNEL=m

这样的配置项。从每个子文件夹的Makefile中也可以找到这些配置项的使用方法,例如arch/arm/Makefile中有如下一行:

plat-$(CONFIG_ARCH_OMAP) := omap

即配置了CONFIG_ARCH_OMAP=y后,plat-y变量就是omap,后面有一行

platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))

说明platdirs会包含arch/arm/plat-omap文件夹

core-y              += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y              += $(machdirs) $(platdirs)

说明会把arch/arm/plat-omap文件夹加入到core-y变量中去,最终编译内核会将core-y变量中的对象全部编译进去。

依照上面的理解过程,通过配置文件的所有项就能找到所有包含的目录和文件,把这些文件添加进Source Insight的工程,就既不会多加又不会少加了。

然而这个方法实现起来困难重重,需要把所有文件夹下的所有Makefile文件全部读一遍,并且把ti8168_evm_defconfig里每个有效配置都去Makefile里搜索一次,实在是费力不讨好。另一种更简单一些的方法是借鉴内核编译的输出。

上述过程实质上就是make工具理解Makefile的过程,它在编译内核时就会自动搜索处理每个目录的Makefile文件,把配置项依次与Makefile匹配,生成一个个目标文件再链接生成最终的完整内核镜像。于是我们就可以把内核编译的输出保存到一个文件中去,通过阅读这个文件知道内核编译了哪些源码,只需要将这些源码添加进工程就可以了。
例如输出文件中有一行:

  CC      init/main.o

说明编译了init/main.c文件,需要把它添加进工程里。

当然,头文件在这里体现不出来,还是要自己添加进去的。

你可能感兴趣的:(linux,kernel)