在make 2.6.36的kernel的时候,会编译出一个bzImage的文件,据说这个是可以引导的文件?
ok,先不管这个,来看看这个是怎么编译出来的吧。
直接输入make指令就会编译出bzImage,说明这个target是默认的target。 好来看看 Makefile里面默认的target 是谁。
# That's our default target when none is given on the command line
PHONY := _all
_all:
好了 人家都说了,默认的是_all
然后又有
_all: all
那就来看看这个all
# The all: target is the default when no target is given on the
# command line.
# This allow a user to issue only 'make' to build a kernel including modules
# Defaults to vmlinux, but the arch makefile usually adds further targets
all: vmlinux
恩,注释也说了,这个又是个默认的target。 生成的是vmlinux。
但是我们要找的bzImage没有发现,看来不在这里。注释里说了,不同的arch的makefile会增加一些target。
那我们来找找。
看到在根目录的Makefile中的前面部分 有
include $(srctree)/arch/$(SRCARCH)/Makefile
这个是不同的arch会include不同的文件,比如是x86的架构就会include arch/x86/Makefile
打开这个文件看到
# Default kernel to build
all: bzImage
好了,我们终于找到这个bzImage的target了,它也是all的一部分。
来看看具体是什么
bzImage: vmlinux
ifeq ($(CONFIG_X86_DECODER_SELFTEST),y)
$(Q)$(MAKE) $(build)=arch/x86/tools posttest
endif
@echo build bzImage $(objtree)
$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
$(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
$(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
其中关键的是$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE),查看log后发现,这句话展开后是
make -f scripts/Makefile.build obj=arch/x86/boot arch/x86/boot/bzImage
也就是说调用了scripts/Makefile.build,那就再来看看这个文件。
这个文件我看了半天不知道是干啥用的,打了点log也没看出来什么名堂。后来我干脆看看它include了什么。
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
这个include看了我半天啊。 总之经过测试是包含了arch/x86/boot/Makefile 。
里面终于出现了bzImage
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
经测试bzImage是call这行产生的。
好不容易找到了if_change的定义,在scripts/Kbuild.include
# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), /
@set -e; /
$(echo-cmd) $(cmd_$(1)); /
echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
这么长,其实就是$(cmd_$(1))做了关键的工作。实际的输出是。
arch/x86/boot/tools/build arch/x86/boot/setup.bin arch/x86/boot/vmlinux.bin CURRENT > arch/x86/boot/bzImage
这个cmd_image也在arch/x86/boot/Makefile中定义。