1.子目录的Makefile
已知有文件:a.c b.c
要在Makefile中设置成编译进内核,可用:obj-y +=a.o b.o 实现
如果用a.c b.c 组合成一个模块ab.o呢?
可用:
obj -m +=ab.o
ab-objs :=a.o b.o
这个在Documentation\kbuild\makefiles.txt有详细说明
2.架构相关的Makefile
根据命令make uimage
分析
搜索uimage发现Uimage并不在顶层Makefile,而在arch/arm/makefile中,这说明arch/arm/下的Makefile肯定被包含在顶层Makefile中,在代码中搜索发现的确如此,如下:
include $(srctree) /arch/$(ARCH)/Makefile
3.顶层Makefile
执行make Uimage 分析他的执行过程,依赖那些文件可以从Makefile入手
搜索可以知道uimage依赖与vmlinux,一步步追踪如下
zImage Image xipImage bootpImage uImage: vmlinux
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
vmlinux-init := $(head-y) $(init-y)
head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o //MMUEXT如果没有被定义,head$(MMUEXT).o就是head.o
init-y := init/
init-y := $(patsubst %/, %/built-in.o, $(init-y))
// 这两句指在init目录下的所有文件会被编译成built-in.o
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
core-y := usr/
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y := $(patsubst %/, %/built-in.o, $(core-y))
// usr/built-in.o arch/arm/kernel/built-in.o arch/arm/mm/ arch/arm/common/built-in.o 就是所指定所有目录下的文件都分别生成built-in.o文件
libs-y := arch/arm/lib/ $(libs-y)
libs-y := $(libs-y1) $(libs-y2)
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
//就是指lib/lib.a 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
这样一级级层层的展开,但是由于Makefile比较复杂,一级级展开工作量大,直接执行make uimage
看具体的执行过程,看是否与分析的一致
图片来源
可以发现是一致的
可以得到分析流程的两大结果
1.第一个文件:arch/arm/kernel/head.S
2.链接脚本(定义内核中的文件怎么排布的): arch/arm/kernel/vmlinux.lds