三 通用目标之make vmlinux的执行过程分析

    我们首先看下vmlinux的规则定义如图3.1,它的依赖除了FORCE以外还有三个,scripts/link-vmlinux.sh是一个用于链接的脚本,我们将在具体讲到该部分内容时再详细分析它。
在这里插入图片描述
                                    图3.1
    vmlinux_prereq的定义如图3.2,仔细一看它的依赖vmlinux-deps就是vmlinux的另一个依赖。除此之外它还有三个命令,但它们都是在配置了某些选项后才会执行的,与我们构造普通的vmlinux没有什么关系,故这里不再展开。
在这里插入图片描述
                                    图3.2
    最后我们来看第三个依赖vmlinux-deps,它的定义如图3.3。它包含了三部分,KBUILD_LDS是其链接脚本,该脚本在每个架构下是不同的,主要是用于定义链接时的规则,比如各个段的布局等
    KBUILD_VMLINUX_INIT为初始化相关的目标,如在arm64架构下head-y目标的定义位于arch/arm64/kernel/Makefile中,其值为head.o,我们都知道linux的入口函数就定义在head.S中,它既是head.o的源文件。至于怎么使head.o成为vmlinux的入口,其实就是KBUILD_LDS定义的链接脚本里定义的。init-y的定义在顶层makefile中,根据图3.4和图3.5可知,其值为init/built-in.o,我们知道该目标就是子目录目标,会由makefile.build脚本进入该目录,然后包含进该目录下的makefile,并递归编译生成最终的built-in.o。
在这里插入图片描述
                                    图3.3
    KBUILD_VMLINUX_MAIN中各变量的定义同样如下图3.4和3.5,它们都是kernel源码下的一级子目录。同样这些目录下的Makefile会被makefile.build递归调用,并最终根据配置生成相应的目标文件以及built-in.o。除了libs-y,它由两个部分lib.a和built-in.o。
在这里插入图片描述
                        图3.4
在这里插入图片描述
                                图3.5
    我们再看下vmlinux-deps的依赖,如图3.6所示它依赖于vmlinux-dirs。
在这里插入图片描述
                            图3.6
    其中vmlinux-dirs的定义位于图3.5中,它们就是将诸如init/,core/等目录最后的/去掉后的值。我们再看下vmlinux-dirs的规则如图3.7:
在这里插入图片描述
                            图3.7
    它依赖于prepare和scripts,prepare目标是由一个多层次的依赖关系构成的。其中数字大的prepare是数字小的prepare的依赖,它们的关系如图3.8所示。它们主要为其后实际的编译做一些准备工作,如prepare3就用于检查当前环境的配置是否是clean的。
在这里插入图片描述
                                 图3.8
    scripts目标的规则如图3.9,其中scripts_basic目标的生成我们在第六章会有介绍,另外两个依赖都是配置文件,我们看下include/config/auto.conf目标是如何生成的。
在这里插入图片描述
                                 图3.9
    它的定义如图3.10,其中KCONFIG_CONFIG的定义如图3.11,即其依赖于.config和auto.conf.cmd。.config和auto.conf.cmd都是make xxxconfig生成的,若它们比auto.conf新,则运行下面的命令以构建目标silentoldconfig,它定义在scripts/kconfig/Makefile中,执行该命会生成include/config/auto.conf和include/generate/autoconf.h文件。
在这里插入图片描述
                                 图3.10
在这里插入图片描述
                图3.11
    asm-generic的定义如图3.12,它会调用Makefile.asm-generated,它的主要功能是生成一些头文件。
在这里插入图片描述
                                 图3.12
    scripts目标调用的命令我们已经很熟悉了,即调用makefile.build,并包含进scripts目录中的makefile,然后执行递归编译。
    好了,终于到正题了。我们看下vmlinux-dirs目标生成的命令:
    $(MAKE) $(build)=$@
    $@是目标vmlinux-dirs的值,根据上面的分析可知它就是一些kernel的顶层子目录,因此该命令就是进入各个子目录,并且执行递归编译,直到所有定义的目标都编译完成。
    让我们再回到vmlinux目标上来,现在它的依赖都已准备好,是时候分析它调用的
命令了。我们回到图3.1中的call命令:
    +$(call if_changed,link-vmlinux)
    根据第六章的分析,我们知道该命令展开后就是cmd_link_vmlinux,它在图3.1中被定义为两个shell命令,其中第二个命令只有在ARCH_POSTLINK有值时才会调用,其定义如图3.13所示,即需要在源码相应架构的目录下存在Makefile.postlink文件,我们通过查看arm64架构下的该目录,没有找到这个文件,故该命令不会被执行。
在这里插入图片描述
                                 图3.13
    接下来我们看第一个命令,这里重写如下:
    $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
    其中CONFIG_SHELL表示用相应的shell解释器执行该命令,$<表示第一个依赖,它的值为scripts/link-vmlinux.sh。因此它的作用是调用link-vmlinux.sh脚本来执行链接,后面都是传给脚本的参数,包括所用的链接器以及链接flags。
    该脚本比较简单,主要通过vmlinux_link函数来链接vmlinux,用mksysmap脚本创建System.map符号表文件等(它其实是通过调用nm命令获取符号的)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值