一. Linux内核源码的make编译
本文对 Linux内核源码的 make时, 顶层Makefile所做的事进行总结。即总结一下 Linux内核源码的 make 过程。
本文续上一篇文章,地址如下:
Linux内核顶层Makefile的make过程说明二_凌肖战的博客-CSDN博客
二. Linux 的 make过程总结
1. vmlinux
当执行 "make" 命令编译 Linux 内核源码时,顶层 Makefile会编译 目标 _all,经过上一篇文章的分析,目标_all 最终依赖于 vmlinux,而在 顶层Makfile中的 vmlinux依赖于如下:
vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
...
+$(call if_changed,link-vmlinux)
这里重点是分析 "scripts/link-vmlinux.sh $(vmlinux-deps) FORCE"。
其中,link-vmlinux.sh 只是个脚本文件,剩下的就是分析 依赖项 vmlinux-deps。
依赖项 vmlinux-deps则 依赖于 $(head-y) 、$(init-y)、$(core-y) 、$(libs-y) 、$(drivers-y) 和 $(net-y) 这六个变量。
上一篇文章已经对这六个变量进行了分析。
这些变量都是一些 built-in.o 或 .a 等文件,这个和oubot 一样,都是将相应目录中的源码文件进行编译,然后在各自目录下生成 built-in.o 文件,有些生成了.a 库文件。最终将这些 built-in.o 和 .a 件进行链接即可形成 ELF 格式的可执行文件,也就是 vmlinux!
2. vmlinux依赖的命令
+$(call if_changed,link-vmlinux)
表示将 $(call if_changed,link-vmlinux) 的结果作为最终生成 vmlinux 的命令,前面的 “+” 表示该命令结果不可忽略。$(call if_changed,link-vmlinux) 是调用函数 if_changed,link-vmlinux 是函数 if_changed 的 参数。
函数 if_changed 定义在文件 scripts/Kbuild.include 中,如下所示:
247 if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
248 @set -e; \
249 $(echo-cmd) $(cmd_$(1)); \
250 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
914 # Final link of vmlinux
915 cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS)
$(LDFLAGS_vmlinux)
916 quiet_cmd_link-vmlinux = LINK $@
cmd_link-vmlinux = /bin/bash scripts/link-vmlinux.sh arm-linux-gnueabihf-ld -EL -p --noundefined -X --pic-veneer --build-id
3. vmliux_link 函数
51 vmlinux_link()
52 {
53 local lds="${objtree}/${KBUILD_LDS}"
54
55 if [ "${SRCARCH}" != "um" ]; then
56 ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
57 -T ${lds} ${KBUILD_VMLINUX_INIT} \
58 --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
59 else
60 ${CC} ${CFLAGS_vmlinux} -o ${2} \
61 -Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \
62 -Wl,--start-group \
63 ${KBUILD_VMLINUX_MAIN} \
64 -Wl,--end-group \
65 -lutil ${1}
66 rm -f linux
67 fi
68 }
......
216 info LD vmlinux
217 vmlinux_link "${kallsymso}" vmlinux