分析vmlinux可执行文件是如何生成的?
已知该vmlinux与compressed路径下的vmlinux不是同一个,是位于内核源码顶层目录下的vmlinux,并且这个vmlinux是make的一部分,因此从内核源码顶层目录下的Makefile文件搜索相关信息
在内核源码顶层目录下的Makefile搜索到该信息:
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
+$(call if_changed,link-vmlinux)
打印发现变量link-vmlinux就只是link-vmlinux
打印依赖($vmlinux-deps)发现是如此长一串:不知道是些啥
arch/arm/kernel/vmlinux.lds arch/arm/kernel/head.o init/built-in.a usr/built-in.a arch/arm/built-in.a arch/arm/mach-aspeed/built-in.a arch/arm/mach-milbeaut/built-in.a arch/arm/mach-stm32/built-in.a kernel/built-in.a certs/built-in.a mm/built-in.a fs/built-in.a ipc/built-in.a security/built-in.a crypto/built-in.a block/built-in.a arch/arm/lib/built-in.a lib/built-in.a arch/arm/lib/lib.a lib/lib.a drivers/built-in.a sound/built-in.a samples/built-in.a net/built-in.a virt/built-in.a
在Makefile中搜索依赖
在1148行附近搜索到依赖是个啥:
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)
打印这个三个变量的结果为:
KBUILD_LDS
arch/arm/kernel/vmlinux.lds
KBUILD_VMLINUX_OBJS
arch/arm/kernel/head.o init/built-in.a usr/built-in.a arch/arm/built-in.a arch/arm/mach-aspeed/built-in.a arch/arm/mach-milbeaut/built-in.a arch/arm/mach-stm32/built-in.a kernel/built-in.a certs/built-in.a mm/built-in.a fs/built-in.a ipc/built-in.a security/built-in.a crypto/built-in.a block/built-in.a arch/arm/lib/built-in.a lib/built-in.a arch/arm/lib/lib.a lib/lib.a drivers/built-in.a sound/built-in.a samples/built-in.a net/built-in.a virt/built-in.a
KBUILD_VMLINUX_LIBS
222
发现KBUILD_LDS是一个链接文件
KBUILD_VMLINUX_OBJS依然是一大串,不知道是些啥
KBUILD_VMLINUX_LIBS更是啥也没有,还用echo 222确认了一遍是不是真的啥也没有。。
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
+$(call if_changed,link-vmlinux)
回到开头看了眼scripts下的link-vmlinux.sh脚本文件是个啥
发现了注释中有这样的描写
6 # vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_OBJS) and
7 # $(KBUILD_VMLINUX_LIBS). Most are built-in.a files from top-level directories
8 # in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
9 # $(KBUILD_VMLINUX_LIBS) are archives which are linked conditionally
10 # (not within --whole-archive), and do not require symbol indexes added.
11 #
12 # vmlinux
13 # ^
14 # |
15 # +--< $(KBUILD_VMLINUX_OBJS)
16 # | +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
17 # |
18 # +--< $(KBUILD_VMLINUX_LIBS)
19 # | +--< lib/lib.a + more
20 # |
21 # +-< ${kallsymso} (see description in KALLSYMS section)
22 #
根据15/16行,我严重怀疑第7行的变量写错名字了,按照我的理解即
KBUILD_VMLINUX_OBJS大多是内核源码顶层目录下built-in.a之类的文件,在该站上查找的结果是库文件?与built-in.o文件通过链接形成ELF可执行文件,也即vmlinux。
但是这三个变量没有太多包含.o相关的文件信息。。也不知道从哪找了
总结一下的话:
使用顶层目录下/scripts下的link-vmlinux.sh脚本,(中间有个看不明白的变量
autoksyms_recursive)运行后面的依赖。
大概就是将各个目录下的.o文件与.a文件通过链接脚本文件生成一个ELF可执行文件,即vmlinux
整理内核编译流程: uImage/zImage/Image/vmlinx之间关系
uImage使用在zImage使用mkimage工具得到的
uImage在zImage前添加64字节头部信息
Image和arch/arm/boot/compressed/vmlinux关系
zImage是通过vmlinux格式化转换为的文件
rch/arm/boot/compressedvmlinux文件和Image之间关系
将Image镜像文件经过gzip压缩生成rch/arm/boot/compressed/vmlinx镜像文件
rch/arm/boot/compressedvmlinux文件和Image之间关系
Image镜像文件经过gzip压缩生成rch/arm/boot/compressed/vmlinx镜像文件