曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6932|回复: 0
打印 上一主题 下一主题

[Kernel] vmlinux-dirs

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2011-7-22 10:46:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Makefile 对应内核版本:2.6.35.13

在顶层 Makefiel 中可以看到 vmlinux 有如下依赖:
[code=Makefile]# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE[/mw_shl_code]

在顶层 Makefile 里看到:
[code=Makefile]
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;[/mw_shl_code]
可见 vmlinux-init, vmlinux-main, vmlinux-lds 这 3 个目标都依赖于 vmlinux-dirs 。

对于 vmlinux-dirs 的处理在顶层 Makefile 中可看到:
[code=Makefile]
# Handle descending into subdirectories listed in $(vmlinux-dirs)
# Preset locale variables to speed up the build process. Limit locale
# tweaks to this spot to avoid wrong language settings when running
# make menuconfig etc.
# Error messages still appears in the original language

PHONY += $(vmlinux-dirs)
$(vmlinux-dirs): prepare scripts
        $(Q)$(MAKE) $(build)=$@[/mw_shl_code]

vmlinux-dirs 依赖于 prepare scripts 。

在顶层 Makefile 中有:
[code=Makefile]# All the preparing..
prepare: prepare0[/mw_shl_code]

prepare0 的依赖及规则为:
[code=Makefile]prepare0: archprepare FORCE
        $(Q)$(MAKE) $(build)=.
        $(Q)$(MAKE) $(build)=. missing-syscalls[/mw_shl_code]

prepare0 依赖的 archprepare 定义为:
[code=Makefile]archprepare: prepare1 scripts_basic[/mw_shl_code]
scripts_basic 目标在 http://www.groad.net/bbs/read.php?tid-3895.html 这里有讨论。

prepare1 的依赖为:
[code=Makefile]prepare1: prepare2 include/linux/version.h include/generated/utsrelease.h \
                   include/config/auto.conf
        $(cmd_crmodverdir)
[/mw_shl_code]
关于 include/linux/version.h 和 include/generated/utsrelease.h 的相关分析可参考:http://www.groad.net/bbs/read.php?tid-4174.html

关于 include/config/auto.conf 目标可参考 http://www.groad.net/bbs/read.php?tid-4104.html

prepare2 的定义见顶层 Makefile :
[code=Makefile]
# prepare2 creates a makefile if using a separate output directory
prepare2: prepare3 outputmakefile[/mw_shl_code]
outputmakefile 的讨论可参考:http://www.groad.net/bbs/read.php?tid-3895.html

prepare3 的依赖也在定义顶层 Makefile 中:
[code=Makefile]# prepare3 is used to check if we are building in a separate output directory,
# and if so do:
# 1) Check that make has not been executed in the kernel src $(srctree)
prepare3: include/config/kernel.release
[/mw_shl_code]

include/config/kernel.release 的规则定义在顶层 Makefile 中:
[code=Makefile]# Store (new) KERNELRELASE string in include/config/kernel.release
include/config/kernel.release: include/config/auto.conf FORCE
        $(Q)rm -f $@
        $(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@[/mw_shl_code]
include/config/kernel.release 依赖于  include/config/auto.conf,关于 auto.conf 的生成可参考:http://www.groad.net/bbs/read.php?tid-4104.html
现在假设 auto.conf 文件已经生成,那么会执行下面两条命令:
$(Q)rm -f $@ 将原先旧有的 include/config/kernel.release 删除掉。
第 2 条命令是将当前编译内核版本号写入新的 kernel.release 文件中。其中 $(CONFIG_SHELL) 变量测试当前宿主机用的是哪种默认 shell 。

假设上面的依赖都已经更新完毕,现在回头来看 prepare1 底下的 $(cmd_crmodverdir) 命令,该命令定义在顶层 Makefile 中:
[code=Makefile]
# Create temporary dir for module support files
# clean it up only when building all modules
cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
                  $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)[/mw_shl_code]
上面 $(MODVERDIR) 变量的定义在顶层 Makefile 中:
[code=Makefile]# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
# even be read-only.
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions[/mw_shl_code]
如果不是编译外部模块(在命令行中使用 M 选项),那么 $(KBUILD_EXTMOD) 变量为空。也就是说,make vmlinux 时,该变量为空;而如果你编译自己的模块时,才会指定该变量。

另外,当直接执行 make ,make all, make modules 时,$(KBUILD_MODULES) 变量值为 1,而 make vmlinux 时,该变量为 0 。
底下的 if 判断函数里的 “分号” 是因为 $(Q)mkdir -p $(MODVERDIR) 是条 shell 语句,如果一行执行两条命令时,两个命令之间要用分号隔开。

所以这类 $(MODVERDIR) 的值就为 .tmp_versions ,也就是在内核源码目录下先建立了 .tmp_versions 的临时目录,用完之后就会将它删除。

当 prepare1 也被更新之后,转回到 prepare0 。prepare0 底下指令两条命令:
[code=Makefile]$(Q)$(MAKE) $(build)=.
$(Q)$(MAKE) $(build)=. missing-syscalls[/mw_shl_code]
prepare0 中调用了 scripts/Makefile.build ,这里会将顶层目录下的 Kbuild 文件包含进来。看 Kbuild 的注释,主要完成 3 个任务:
1. 生成 bounds.h 文件
2. 生成 asm-offsets.h 文件
3. 检查丢失的系统调用
其中,由 Kbuild 中的:
[code=Makefile]missing-syscalls: scripts/checksyscalls.sh FORCE
        $(call cmd,syscalls)[/mw_shl_code]
知道,检查丢失的系统调用由 scripts/checksyscalls.sh 脚本文件来完成。

最后当所有的依赖都满足后,回到 vmlinux-dirs 的规则中来:
[code=Makefile]$(vmlinux-dirs): prepare scripts
        $(Q)$(MAKE) $(build)=$@[/mw_shl_code]
此时 vmlinux-dirs 的值为:
init usr arch/x86 kernel mm fs ipc security crypto block drivers sound firmware arch/x86/pci arch/x86/power arch/x86/video net lib arch/x86/lib
所以,当 prepare 和 scripts 这两个依赖已经更新就绪后,就会执行下面的 $(Q)$(MAKE) $(build)=$@ 命令,这条命令完整形式为:
make -f scripts/Makefile.build obj=$@
上面的 $@ 表示的就是 $(vmlinux-dirs) 变量所指代的所有目录。
所以,这里就是调用 scripts/Makefile.build,然后在 scripts/Makefile.build 里依次的包含变量 $(vmlinux-dirs) 所对应各目录的 Kbuild/Makefile,最终在各目录中编译出不同的对象文件来(一系列的.o文件和.a文件)。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-17 23:47 , Processed in 0.058208 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表