一. 内核 Makefile 文件的分类
1. 顶层Makefile
它是 Makefile 的核心,从整体上控制着内核的编译与链接。
2. .config
配置文件,决定使用哪些文件。
3. arch/$(ARCH)Makefile
对应体系结构的Makefile,它决定哪些体系结构相关的文件参于内核生成。
4. script/Makefile.*
Makefile 通过的规则脚本。
5. KBuild Makefile
各级子目录的Makefile,被上层目录的Makefile调用来编译当前目录下的文件。
二. 内核 Makefile 的组织与执行
分析makefile的结构最好从顶层原文件分析,一般我们编译内核会使用make uImage或make命令,于是我们就从命令的关健字开始搜索。
搜索:uImage
顶层Makefile没找到,于是我们在arch/arm/Makefile下搜索找到:zImage Image xipImage bootpImage uImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@得到:uImage 依赖于 vmlinux
搜索:include
include $(srctree)/arch/$(ARCH)/Makefile得到:顶层 Makefile 是包含子目录的 Makefile 的。
搜索:auto.conf
-include include/config/auto.conf得到:自动生成的 auto.conf 也是被顶层的 Makefile 包含的。
搜索:vmlinux
all: vmlinux发现:如果make不加任何参数,只会生成vmlinux
# vmlinux image - including updated kernel symbols vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE得到:vmlinux依赖于后面的一堆东西
vmlinux-init := $(head-y) $(init-y) head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o相当于: arch/arm/kernel/head$.o arch/arm/kernel/init_task.o
init-y := init/ init-y := $(patsubst %/, %/built-in.o, $(init-y))相当于: init/built-in.o
搜索:vmlinux-main
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)得到:vmlinux-main 依赖于core-y, libs-y, drivers-y, net-y
core-y := usr/ core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ core-y := $(patsubst %/, %/built-in.o, $(core-y))
相当于: usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o
libs-y := lib/ libs-y := $(libs-y1) $(libs-y2) libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))相当于: lib/lib.a lib/built-in.o
drivers-y := drivers/ sound/ drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))相当于: drivers/built-in.o sound/built-in.o
net-y := net/ net-y := $(patsubst %/, %/built-in.o, $(net-y))相当于: net/built-in.o
make uImage V=1打印信息有如下:
arm-linux-ld -EL -p --no-undefined -X -o vmlinux -T arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o arch/arm/kernel/init_task.o init/built-in.o --start-group usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/built-in.o arch/arm/common/built-in.o arch/arm/mach-s3c2410/built-in.o arch/arm/mach-s3c2400/built-in.o arch/arm/mach-s3c2412/built-in.o arch/arm/mach-s3c2440/built-in.o arch/arm/mach-s3c2442/built-in.o arch/arm/mach-s3c2443/built-in.o arch/arm/nwfpe/built-in.o arch/arm/plat-s3c24xx/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o security/built-in.o crypto/built-in.o block/built-in.o arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o drivers/built-in.o sound/built-in.o net/built-in.o --end-group .tmp_kallsyms2.o
从这里我们得到:
arch/arm/kernel/vmlinux.lds:内核的链接脚本。
arch/arm/kernel/head.o:内核心启动的是第一个文件。