Makefile结构分析-----uClinux (2.6.x内核)系统映像过程刘江欧阳昭暐吕熙隆1、源代码文件及目录构成解压缩uClinux-dist-20070130.tar.gz压缩文件,在uClinux-dist原始子目录下主要有:config、Bin、linux-2.4.x、linux-2.6.x 、lib、tools、Include、user和vendors,以及文件Makefile。
另外,在编译后生成子目录images和romfs,以及文件autoconfig.h、config.in和两个隐含文件:.config和.depend。
config子目录包含文件及下一级子目录,如config.in、configure.help、Fixconfig、Makefile、Mkconfig、Setconfig所有这些文件及子目录Scripts均与系统配置有关;linux-2.6.x子目录是嵌入式操作系统uClinux-2.6.x的核心目录,包括下一级子目录arch、include、init、drivers、fs、ipc、kernel、lib、Mm、scripts和关键文件Makefile、rules.make,编译后还要生成新文件romfs.o、linux和system.map;lib子目录为嵌入式操作系统提供压缩和改进了的函数库支持;tools子目录包含romfs-inst.sh文件,通过调用此文件,可以把目录或文件加入到romfs子目录中;user子目录包含各种驱动程序文件目录,根据用户的配置情况,不同的驱动程序会被编译进最后形成的操作系统中;vendors子目录包括与特定硬件平台相关的分类目录组。
目录结构如图1所示。
Makefile的详细介绍情况在uClinux-dist\linux-2.6.x\Documentation\kbuild中,如图2所示。
图1、目录结构即Linux 内核中的 Makefile 以及与 Makefile 直接相关的文件有:a. Makefile:顶层 Makefile,是整个内核配置、编译的总体控制文件。
b. .config:内核配置文件,包含由用户选择的配置选项,用来存放内核配置后的结果(如 make config)。
c. arch/*/Makefile:位于各种 CPU 体系目录下的 Makefile,如arch/arm/Makefile,是针对特定平台的 Makefile。
d. 各个子目录下的 Makefile:比如 drivers/Makefile,负责所在子目录下源代码的管理。
e. Rules.make:规则文件,被所有的 Makefile 使用。
图2、make说明文档2、编译过程简介该编译过程的方法在uClinux-dist/ linux-2.6.x /Readme中有详细描述。
将uClinux-dist-20070130.tar.gz放入/usr目录中,依次在终端输入如下命令:# cd /usr/# tar –zxvf uClinux-dist-20070130.tar.gz# cd uClinux-dist (Cd into the source tree)# make clean# make config (Configure the build target)# make dep (Build the dependencies)# make (Build the image)终端提示在/image目录下成功生成映像文件。
3、核心Make文件运行分析3.1、make clean执行情况分析3.1.1 uClinux-dist/Makefile中的clean命令图3、核心makefile中clean代码在根目录Makefile可以找到LINUXDIR = $(CONFIG_LINUXDIR), CONFIG_ LINUXDIR定义在前面生成的.config文件中,CONFIG_LINUXDIR =linux-2.6.x。
所以执行该核心makefile首先调用modules clean命令进行扩充(modules_clean: -[ ! -d modules ] || $(MAKEARCH) -C modules clean),然后命令再执行删除/ linux-2.6.x/目录下以前编译生成的linux、asm、perlasm等文件。
3.1.2 uClinux-dist/ linux-2.6.x /Makefile中的clean命令在/linux-2.6.x/Makefile文件中,make clean相关部分代码如下:图4、linux-2.6.x /Makefile中clean代码"make clean"删除几乎所有的在编译内核时生成的文件,该命令首先删除相同目录下的文件和目录CLEAN_FILES,CLEAN_DIRS,接着通过archclean命令进行扩充。
此外,在"make clean"还会删除匹配 "*.[oas]","*.ko" 的文件。
Archclean在/linux-2.6.x/arch/arm/Makefile中,相关代码如下:图5、/arch/arm/Makefile中archclean代码当"make clean"执行时,make会递归访问archclean并清理boot,因此,make clean就相当于make archclean。
具有清除功能的命令还有make mrproper、make distclean。
他们和make clean 有区别,具体在核心Makefile中有说明,如图6所示:图6、/arch/arm/Makefile中archclean代码没搞清楚uClinux-dist/Makefile和uClinux-dist/ linux-2.6.x /Makefile中clean的联系,猜测在uClinux-dist/执行make clean命令时,根本不调用uClinux-dist/ linux-2.6.x /Makefile中clean命令。
3.2、make config执行情况分析make config的功能是完成系统配置,在uClinux-dist/文件中,源代码如图7所示:图7、核心makefile中config代码图8、核心makefile中config.in代码从该代码可以看出make config用scripts/Configure去解释执行在uClinux-dist/config/mkconfig/目录下的congif.in,同时还调用执行该目录下的setconfig配置文件进行环境设置。
由此可见uClinux-dist/ makefile只是个索引,最终调用指向uClinux-dist/config/Makefile。
在uClinux-dist/config/Makefile文件中,源代码如图9所示:图9、四种?config代码比较从该代码可以看出make config用scripts/Configure去解释执行在当前目录下的congif.in;make oldconfig配置情况与make config基本相同,仅仅多了一个参数 –d,大概表示它要使用默认配置文件的意思。
make menuconfig与前两种相比有很大的不同,虽然依然使用了config.in文件,但使用电工具不同,是Menuconfig,并且在开始部分还有一些准备工作要做。
主要因为将config.in转化为菜单形式,用户工作界面有较大的改进,工作就要复杂一些。
Make Xconfig更加复杂,首先要制作合理的文件,然后用wish执行,使config.in转变为xwindows方式进行系统配置的工具。
因此,以上四种配置方式在完成系统赋予的使命上功能是一致的,只不过操作界面有所不同。
用户通过 make config 配置后,产生了 .config。
顶层 Makefile 读入 .config 中的配置选择。
顶层 Makefile 有两个主要的任务:产生 vmlinux(未压缩的内核)文件和内核模块(module)。
为了达到此目的,顶层 Makefile 递归的进入到内核的各个子目录中,分别调用位于这些子目录中的 Makefile。
至于到底进入哪些子目录,取决于内核的配置。
在顶层 Makefile 中,有一句:include arch/$(ARCH)/Makefile,包含了特定 CPU 体系结构下的 Makefile,这个 Makefile 中包含了平台相关的信息。
3.3、make dep执行情况分析make dep读取系统配置以创建编译时可依赖的关系树,结果被存储在隐含文件.depend中,makefile通过包含.depend文件来包含这种依赖关系树,用于指导编译。
在uClinux-dist/makefile中dep代码如图10所示:图10、核心makefile中dep代码该代码告诉我们在/ linux-2.6.x/.config文件,如果找不到提示错误退出,反之执行该目录下的dep命令(假定配置时选定的为linux-2.6.新的内核),而在该目录下该命令根本找不到。
即使具有类似功能的depend dep仅有一个文本输出的提示信息。
depend dep:@echo '*** Warning: make $@ is unnecessary now.'由此可见,该命令主要是针对以前编译2.4内核的时候用的,以保证编译内核时所有的依赖,例如头文件,都存在。
但对于2.6来讲已经不需要了,直接一个make命令把make dep和make zImage的事请就做了。
3.4、make执行情况分析在Makefile中提供了配置编译选项的各种规则,执行make help命令可以打印出详细的帮助信息,从中我们可以看出执行“#make”或执行“make all”,将自动编译带“*”的目标,即自动自动编译vmlinux、modules、zImage(或xipImage)。
在uClinux-dist/目录下运行#make命令,进行编译链接内核映像,从makefile关联关系看,过程应该是:先编译链接生成顶层目录的vmlinux,然后再把vmlinux精简压缩成piggy.gz,最后加上自引导程序链接成linux-2.6.x/arch/arm/boot/zImage,这是一个具备自启动能力的linux内核映像。
对最后一步make命令详细分析如下:3.4.1 [uClinux-dist/makefile]: /*根目录下的入口*/(1) 找到makefile程序执行的入口,如图11所示。