对linux内核makefile的一点点研究
包含CONFIG_EXT3_FS=y
等数据的文件include/config/auto.conf
---- include/linux/version.h ----
include $(srctree)/arch/$(SRCARCH)/Makefile
我们的ARCH为arm,所以
将包含进arch/arm/Makefile
而archprepare在这里有了第1依赖文件
archprepare: maketools
maketools: include/linux/version.h FORCE
然后将根据如下顺序,依次执行依赖检查[luther.gliethttp]
prepare3: include/config/kernel.release
prepare2: prepare3 outputmakefile
prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
include/asm include/config/auto.conf
可以看到prepare1将依次检查依赖prepare2,
include/linux/version.h,include/linux/utsrelease.h
然后include/asm,最后是include/config/auto.conf
当prepare1执行完毕之后,随即archprepare的另一个依赖scripts_basic将被继续执行.
当archprepare所有依赖执行完毕之后,随即prepare0的命令将被执行
archprepare: prepare1 scripts_basic
prepare0: archprepare FORCE
$(Q)$(MAKE) $(build)=.
$(Q)$(MAKE) $(build)=. missing-syscalls
prepare: prepare0
而scripts/Makefile.build首先清除所有变量,然后include Kbuild
而我们可以看到$(builtin-target) $(lib-target) $(extra-y)全为空
同时$(obj-m) $(modorder-target)将因为$(obj-m),而只剩下$(modorder-target)
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
所以翻译后为
__build: $(modorder-target) $(always)
$(modorder-target): $(subdir-ym) FORCE
$(Q)(cat /dev/null; $(modorder-cmds)) > $@
又因为./Kbuild包含内容为
bounds-file := include/linux/bounds.h
always := $(bounds-file)
targets := $(bounds-file) kernel/bounds.s
offsets-file := include/asm/asm-offsets.h
always += $(offsets-file)
targets += $(offsets-file)
targets += arch/$(SRCARCH)/kernel/asm-offsets.s
kernel/bounds.s: kernel/bounds.c FORCE
$(Q)mkdir -p $(dir $@)
$(call if_changed_dep,cc_s_c)
$(obj)/$(bounds-file): kernel/bounds.s Kbuild
$(Q)mkdir -p $(dir $@)
$(call cmd,bounds)
arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
$(obj)/$(bounds-file) FORCE
$(Q)mkdir -p $(dir $@)
$(call if_changed_dep,cc_s_c)
$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
$(call cmd,offsets)
接下来就是检查依赖scripts的具体实现了
scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@)
因为scripts/Makefile
包含了subdir-y += mod
同时kernel/scripts/Makefile.lib
subdir-ym := $(sort $(subdir-y) $(subdir-m))
又被添加到了subdir-ym变量中
在scripts/Makefile.build中就有定义了处理目标的规则了
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@
而最终目标__build又依赖$(subdir-ym)
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
所以可以看到
make $(build)=mod
将被执行
ok上面的所有事情都做完之后,下面是vmlinux包含的所有dirs编译规则统一处理入口[luher.gliehtttp]
$(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
比如
1. ARCH=arm make s3c6400_defconfig
2. ARCH=arm CROSS_COMPILE=arm-eabi- make
他默认的$(vmlinux-dirs)内容如下[luther.gliethttp]
init usr arch/arm/kernel arch/arm/mm arch/arm/common arch/arm/mach-s3c6400 arch/arm/mach-s3c6410 arch/arm/plat-s3c64xx arch/arm/plat-s3c arch/arm/vfp kernel mm fs ipc security crypto block drivers sound firmware net arch/arm/lib lib
include $(srctree)/arch/$(SRCARCH)/Makefile
即arch/arm/Makefile
zImage Image xipImage bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
我们看看./Makefile
# vmlinux
# ^
# |
# +-< $(vmlinux-init)
# | +--< init/version.o + more
# |
# +--< $(vmlinux-main)
# | +--< driver/built-in.o mm/built-in.o + more
# |
# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE
$(call if_changed_rule,vmlinux-modpost)
阅读(6744) | 评论(1) | 转发(3) |