linux内核编译系统-kbuild系统详解
scripts/Makefile.lib
这里可以看到,scripts/Makefile.build执行时会include .config文件。.config是make menuconfig后生成的内核配置文件。
里面有如下语句:
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_ASUS=m
CONFIG_ACPI_IBM=m
。。。
以前我一直对它的格式表示奇怪,现在很清楚了,它们是作为makefile的一部分,通过读取CONFIG_XXX的值就可以知道他们是作为模块还是作为内核的一部分而编译的。
此外,还包含了$(obj)/Makefile。这就是通过在make时传递目录名$(obj)间接调用Makefile的手法。对于内核普通代码所对应的Makefile而言,里面只是对obj-m obj-y,-objs等变量进行赋值操作。
接下去是include scripts/Makefile.lib
。正如它的文件名所示,这类似于一个库文件。它负责对obj-m obj-y,-objs等变量进行加工处理。从中提取出subdir-ym等变量,这是个很重要的变量,记录了需要递归调用的子目录。以后递归调用Makefile全靠它了。这里也充分体现了GNU make对字符串进行操作的强大功能。
回到Makefile.build。这时,重要变量$(builtin-target),$(subdir-ym)等都已经计算完毕。开始列依赖关系和具体操作了。
079 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
080 $(if $(KBUILD_MODULES),$(obj-m)) \
081 $(subdir-ym) $(always)
082 @:
$(builtin-target)是指当前目录下的目标文件,即$(obj)/built-in.o
如前文所说,$(subdir-ym)用来递归调用子目录的Makefile
306 # Descending
307 # ---------------------------------------------------------------------------
308
309 .PHONY: $(subdir-ym)
310 $(subdir-ym):
311 $(Q)$(MAKE) $(build)=$@
通过这种方式,实现了对某个目录及其子目录的编译。
分析完Makefile.build,回过头来再看bzImage.从arch/i386/Makefile中可以看到,bzImage是在vmlinux基础上加以压缩拼接而成。从vmlinux到bzImage的过程在《读核感悟-
Linux内核
启动-内核的生成》中已经有介绍。现在看看vmlinux是如何生成的。
见/usr/src/linux/Makefile
728 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
729 $(call if_changed_rule,vmlinux__)
611 vmlinux-init := $(head-y) $(init-y)
612 vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
613 vmlinux-all := $(vmlinux-init) $(vmlinux-main)
614 vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
vmlinux所依赖的目标$(vmlinux-lds) 是对arch/i386/kernel/vmlinux.lds.S进行预处理的结果:arch/i386/kernel/vmlinux.lds ,其它的依赖关系也都可以在/usr/src/linux/Makefile中查到。
所以,当用户在源代码目录下执行make bzImage。make会检查bzImage的依赖目标,然后不停地递归调用各个Makefile,最终生成一个bzImage文件。
如果我们换个角度,还可以归纳出不少有趣的东西。如果把make看成是一种脚本语言,那么Makefile就是代码。make就是解释器。make里也有函数,也有变量。通过定义目标,可以实现类似于函数的效果。而目标之间的依赖关系则类似于函数内部再调用其它函数。
如果我们考虑变量的作用域,还可以归纳出以下几点:
1.Makefile内部定义的变量作用域只限于那个Makefile中,如obj-m。
2.要使变量的作用域扩展到整个make命令的执行过程(包括递归调用的其它Makefile),需要使用export命令。
调用Makefile的方式也有很多种:
1.一种是隐式调用,如运行make,它会自动在当前目录寻找Makefile等。
2.一种是显式调用,如用make -f指定。
3.一种是用include 来调用。
- VXWORKS内核分析(11-11)
- linux内核编译步骤(11-11)
- Linux内核解读入门(11-09)
- Linux内核编译过程详解(kernel2.6.7) (04-16)
- 嵌入式Linux内核移植相关代码分析(04-21)
- 什么是module 以及如何写一个module(转)(04-23)