.o文件 linux生成,vmlinux.o 生成

vmlinux.o Makefile 对应内核版本:2.6.35.13

vmlinux.o 是生成 vmlinux 的依赖之一,在链接出 vmlinux 之前会先链接出 vmlinux.o 。

vmlinux.o 定义在顶层 Makefile 中:

vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE

$(call if_changed_rule,vmlinux-modpost)

上面 $(modpost-init) 定义在顶层 Makefile 中:

modpost-init := $(filter-out init/built-in.o, $(vmlinux-init))

它只是从

$(vmlinux-init)中去掉 init/built-in.o 文件。比如在默认的配置下,$(vmlinux-init) 指代的生成文件为:

arch/x86/kernel/head_32.o arch/x86/kernel/head32.o arch/x86/kernel/head.o arch/x86/kernel/init_task.o init/built-in.o

则 $(modpost-init) 就是:

arch/x86/kernel/head_32.o arch/x86/kernel/head32.o arch/x86/kernel/head.o arch/x86/kernel/init_task.o

在 vmlinux.o 底下的 if_changed_rule 函数和

if_changed 函数类似,它会使构建系统调用 rule_vmlinux-modpost --- 该变量也定义在顶层 Makefile 中:

define rule_vmlinux-modpost

:

+$(call cmd,vmlinux-modpost)

$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@

$(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd

endef

一开始就使用 $(call cmd,vmlinux-modpost) 即为 cmd_vmlinux-modpost ,它也定义在顶层 Makefile 中:

cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@                          \

$(vmlinux-init) --start-group $(vmlinux-main) --end-group             \

$(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)

上面 $(LD) 即为 ld 链接命令。

$(LDFLAGS) 指代 -m elf_i386 (编译内核在 x86 平台,如果是交叉编译,则 -m 选项后会有相应更改)。

ld 的 --start-group 和 --end-group 之间放置目标文件列表,ld 会对列表中列出的目标文件进行重复的搜索,目的是查看各个文件之间再也没有未决的互相引用,当然这么做是相当耗时的,除非是非做不可。自然的,对于内核而言,这非做不可。

接着

$(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^) 是从所有的依赖中去掉伪目标 FORCE,$(vmlinux-init) 和 $(vmlinux-main) 这几个依赖后看看还有什么别的依赖。默认配置情况下没有,所以这里为空。

在链接出 vmlinux.o 目标后,接着使用 scripts/Makefile.modpost 这个文件来处理 vmlinux.o 目标。跟到  scripts/Makefile.modpost 中看到:

vmlinux.o: FORCE

$(call cmd,kernel-mod)

所以执行的是 cmd_kernel-mod 中的语句,这些语句也在 scripts/Makefile.modpost 中:

quiet_cmd_kernel-mod = MODPOST $@

cmd_kernel-mod = $(modpost) $@

其中  $(modpost) 的定义为:

# Step 2), invoke modpost

#  Includes step 3,4

modpost = scripts/mod/modpost                    \

$(if $(CONFIG_MODVERSIONS),-m)                  \

$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,)       \

$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile)   \

$(if $(KBUILD_EXTMOD),-I $(modulesymfile))      \

$(if $(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS))) \

$(if $(KBUILD_EXTMOD),-o $(modulesymfile))      \

$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \

$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \

$(if $(cross_build),-c)

由上可见,这里实际使用的是  scripts/mod/ 目录下的 modpost 用来解析 vmlinux.o 对象文件,它检查目标中的 sections 是否 mis match,然后还将基本内核导出的所有符号都记录到文件 Module.symvers 中去。详情可以看 Makefile.modpost 中的注释以及参考 scripts/mod/modpost.c 中的代码。

在上面的诸多判断中,在默认的内核配置下,CONFIG_MODVERSION,CONFIG_MODULE_SRCVERSION,KBUILD_EXTMOD,KBUILD_EXTRA_SYMBOLS,CONFIG_DEBUG_SECTION_MISMATCH 以及 KBUILD_MODPOST_WARN 这些变量都为空,所以最后综合起来得到的命令为:

scripts/mod/modpost -o /home/beyes/Downloads/linux-2.6.35.13/Module.symvers -S vmlinux.o

上面调用 modpost 处理完后,再返回到主 Makefile 中,使用

$(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd 将编译 vmlinux.o 的命令写入到.vmlinux.o.cmd 文件中保存起来,以便下次再编译内核时可以进行新旧命令的比较。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值