本篇基于上一篇<<linux内核make menuconfig执行过程>>基础上,追溯make执行过程。
make
1. 与make menuconfig相同的部分
? 这部分内容与make menuconfig执行条件相同,并且变量值相同,可以忽略。 ? 打开Makefile文件:
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 9
SUBLEVEL = 0
EXTRAVERSION =
NAME = Kleptomaniac Octopus
? 在开始的地方定义了linux版本信息,这些将在后面多次使用。
? …
$(if $(filter __%, $(MAKECMDGOALS)), \
$(error targets prefixed with '__' are only for internal use))
? MAKECMDGOALS属执行make时传入的参数(暂存到这个变量),比如输入make test,将会匹配到,执行 $(error targets prefixed with ‘__’ are only for internal use)),导致make停止执行
? …
PHONY := __all
__all:
? 当make时没有传入参数规则,将默认执行__all流程
? …
ifneq ($(sub_make_done),1)
? 判断子级make配置是否完成,如果还没有完成执行条件内的语句
? …
unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC
? 不让LC_ALL变量传入子级make(使用),传入LC_COLLATE LC_NUMERIC
? …
ifeq ("$(origin V)", "command line")
KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = 0
endif
? 如果KBUILD_VERBOSE等于0,则上述命令将被隐藏;如果KBUILD_VERBOSE等于1,则显示上述命令;如果KBUILD_VERBOSE等于2,请给出重建每个目标的原因。 ? 这里默认执行KBUILD_VERBOSE = 0(quiet=quiet_,Q = @,只打印执行结果)
? …
export quiet Q KBUILD_VERBOSE
? quiet Q KBUILD_VERBOSE变量传入子级make(使用)
? …
ifeq ("$(origin O)", "command line")
KBUILD_OUTPUT := $(O)
endif
ifneq ($(KBUILD_OUTPUT),)
# Make's built-in functions such as $(abspath ...), $(realpath ...) cannot
# expand a shell special character '~'. We use a somewhat tedious way here.
abs_objtree := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
$(if $(abs_objtree),, \
$(error failed to create output directory "$(KBUILD_OUTPUT)"))
? 通过(make) O=指定输出目录或者通过KBUILD_OUTPUT变量,O=优先级高级KBUILD_OUTPUT变量,默认值为当前目录
? …
abs_srctree := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
? abs_srctree得到Makefile绝对路径(由MAKEFILE_LIST变量经过 lastword、dir、realpath执行得到)
? …
ifneq ($(abs_srctree),$(abs_objtree))
MAKEFLAGS += --include-dir=$(abs_srctree)
need-sub-make := 1
endif
? 在make menuconfig中abs_srctree与abs_objtree相同,未设置need-sub-make,need-sub-make=0
? …
this-makefile := $(lastword $(MAKEFILE_LIST))
? this-makefile=Makefile
? …
export sub_make_done := 1
? 子级make配置完成
? …
ifeq ($(need-sub-make),1)
PHONY += $(MAKECMDGOALS) __sub-make
$(filter-out $(this-makefile), $(MAKECMDGOALS)) __all: __sub-make
@:
__sub-make:
$(Q)$(MAKE) -C $(abs_objtree) -f $(abs_srctree)/Makefile $(MAKECMDGOALS)
...
? 上述说过need-sub-make=0,这里的分支将不执行(不执行子级Makefile)
? …
ifeq ($(need-sub-make),)
MAKEFLAGS += --no-print-directory
? 进入分支,设置输出信息
? …
ifeq ("$(origin C)", "command line")
KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
KBUILD_CHECKSRC = 0
endif
? 使用“make C=1”只允许检查重新编译的文件,使用“make C=2”来启用对所有源文件的检查;这里为0,执行KBUILD_CHECKSRC = 0
? …
ifeq ("$(origin M)", "command line")
KBUILD_EXTMOD := $(M)
endif
$(if $(word 2, $(KBUILD_EXTMOD)), \
$(error building multiple external modules is not supported))
export KBUILD_CHECKSRC KBUILD_EXTMOD
? 设置外部模块(.ko)目录
? …
extmod-prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)
? extmod-prefix默认为空
? …
ifeq ($(abs_srctree),$(abs_objtree))
# building in the source tree
srctree := .
building_out_of_srctree :=
else
ifeq ($(abs_srctree)/,$(dir $(abs_objtree)))
# building in a subdirectory of the source tree
srctree := ..
else
srctree := $(abs_srctree)
endif
building_out_of_srctree := 1
endif
? abs_srctree与abs_objtree目录相同,srctree为当前目录,building_out_of_srctree为空
? …
objtree := .
VPATH := $(srctree)
? objtree为当前目录,VPATH为空
? …
export building_out_of_srctree srctree objtree VPATH
? building_out_of_srctree srctree objtree VPATH变量传入子级make(使用)
? …
version_h := include/generated/uapi/linux/version.h
old_version_h := include/linux/version.h
clean-targets := %clean mrproper cleandocs
...
? 定义version_h、old_version_h路径,clean-targets清除规则等配置
? …
ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter %config,$(MAKECMDGOALS)),)
config-build := 1
ifneq ($(words $(MAKECMDGOALS)),1)
mixed-build := 1
endif
endif
endif
? …
ARCH ?= $(SUBARCH)
? 获取当前系统架构,默认x86
? …
...
USERINCLUDE := \
-I$(srctree)/arch/$(SRCARCH)/include/uapi \
-I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \
-I$(srctree)/include/uapi \
-I$(objtree)/include/generated/uapi \
-include $(srctree)/include/linux/kconfig.h
? 跳过gcc等一些编译相关信息,USERINCLUDE为-I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h
? …
LINUXINCLUDE := \
-I$(srctree)/arch/$(SRCARCH)/include \
-I$(objtree)/arch/$(SRCARCH)/include/generated \
$(if $(building_out_of_srctree),-I$(srctree)/include) \
-I$(objtree)/include \
$(USERINCLUDE)
? LINUXINCLUDE为-I./arch/x86/include -I./arch/x86/include/generated -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h
? …
export KBUILD_LDS_MODULE := $(srctree)/scripts/module-common.lds
...
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
? 导入较多变量供子级make使用
? …
PHONY += outputmakefile
? PHONY为__all scripts_basic outputmakefile
? …
outputmakefile:
? 执行outputmakefile内分支,make menuconfig只是经过一下这里
2.make执行部分
? …
ifdef config-build
...
else #!config-build //执行这部分分支
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
__all: all
else
__all: modules
endif
? __all为all,PHONY为__all scripts_basic outputmakefile all,构建包括vmlinux、特定于arch、clean和其他的目标。一般来说,除了*config目标之外,所有目标都是。
? …
export KBUILD_MODULES KBUILD_BUILTIN
? KBUILD_MODULES=1, KBUILD_BUILTIN=1
? …
ifdef need-config
include include/config/auto.conf
endif
? 包含auto.conf,need-config=1
? …
ifeq ($(KBUILD_EXTMOD),)
# Objects we will link into vmlinux / subdirs we need to visit
core-y := init/ usr/
drivers-y := drivers/ sound/
drivers-$(CONFIG_SAMPLES) += samples/
drivers-y += net/ virt/
libs-y := lib/
endif # KBUILD_EXTMOD
? 进入分支,链接到需要访问的vmlinux/subdirs的对象
? …
all: vmlinux
? 没有指定目标时(如只执行make),all:target是默认值,默认为vmlinux,但arch makefile通常会添加更多目标
? …
CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \
$(call cc-option,-fno-tree-loop-im) \
$(call cc-disable-warning,maybe-uninitialized,)
export CFLAGS_GCOV
? 增加编译标志:-fprofile-arcs -ftest-coverage -fno-tree-loop-im -Wno-maybe-uninitialized
? …
include arch/$(SRCARCH)/Makefile
? 包含arch/x86/Makefile
? …
ifdef need-config
ifdef may-sync-config
# Read in dependencies to all Kconfig* files, make sure to run syncconfig if
# changes are detected. This should be included after arch/$(SRCARCH)/Makefile
# because some architectures define CROSS_COMPILE there.
include include/config/auto.conf.cmd
$(KCONFIG_CONFIG):
? 进入分支,KCONFIG_CONFIG默认.config
? …
ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
KBUILD_CFLAGS += -O2
else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
KBUILD_CFLAGS += -O3
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
endif
? 执行KBUILD_CFLAGS += -O2,KBUILD_CFLAGS为-Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE -Werror=implicit-function-declaration -Werror=implicit-int -Wno-format-security -std=gnu89 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -fno-jump-tables -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-address-of-packed-member -O2
? …
DEBUG_CFLAGS := $(call cc-option, -fno-var-tracking-assignments)
? DEBUG_CFLAGS为-fno-var-tracking-assignments
? …
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
? arch Makefile可能会覆盖CC,所以在包含arch Makefile后保留此选项,NOSTDINC_FLAGS为-nostdinc -isystem /opt/ohpc/pub/compiler/gcc/9.3.0/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include
? …
ifdef CONFIG_RETPOLINE
KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
endif
? CONFIG_RETPOLINE为y,进入分支,确保在使用retpoline时禁用-fcf保护,因为它与-mindirect branch=thunk-extern不兼容
? …
include-y := scripts/Makefile.extrawarn
include-$(CONFIG_KASAN) += scripts/Makefile.kasan
include-$(CONFIG_KCSAN) += scripts/Makefile.kcsan
include-$(CONFIG_UBSAN) += scripts/Makefile.ubsan
include-$(CONFIG_KCOV) += scripts/Makefile.kcov
include-$(CONFIG_GCC_PLUGINS) += scripts/Makefile.gcc-plugins
include $(addprefix $(srctree)/, $(include-y))
? include $(addprefix $(srctree)/, $(include-y))为./scripts/Makefile.extrawarn,默认只有Makefile.extrawarn生效
? …
export KBUILD_IMAGE ?= vmlinux
? KBUILD_IMAGE为arch/x86/boot/bzImage
? …
export INSTALL_PATH ?= /boot
? INSTALL_PATH为/boot
? …
export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE)
? INSTALL_DTBS_PATH为/boot/dtbs/5.9.0
? …
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
? MODLIB 为/lib/modules/5.9.0
? …
PHONY += prepare0
? PHONY增加prepare0,下面看prepare0相关内容
? …
PHONY += prepare archprepare
archprepare: outputmakefile archheaders archscripts scripts include/config/kernel.release \
asm-generic $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
include/generated/autoconf.h
prepare0: archprepare
...
# All the preparing..
prepare: prepare0 prepare-objtool prepare-resolve_btfids
? prepare0依赖于archprepare,而archprepare依赖于outputmakefile archheaders archscripts scripts。outputmakefile未进入判断条件,现在看下archheaders
? …
archheaders:
$(Q)$(MAKE) $(build)=arch/x86/entry/syscalls all
? 在arch/x86/Makefile中搜到这个分支(上述include arch/x86/Makefile),生成的系统调用列表syscall table。分析archscripts
? …
archscripts: scripts_basic
$(Q)$(MAKE) $(build)=arch/x86/tools relocs
? 同样在arch/x86/Makefile中,archscripts生成relocs工具,依赖于scripts_basic
? …
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
? scripts_basic执行make build=scripts/basic和rm -f指令,查看scripts/basic文件夹
? …
hostprogs-always-y += fixdep
? scripts/basic/Makefile生成fixdep工具
? …
PHONY += scripts
scripts: scripts_basic scripts_dtc
$(Q)$(MAKE) $(build)=$(@)
? 执行make build=scripts,在srcripts/Makefile中可以看到,生成bin2c、kallsyms、asn1_compiler等工具,并且依赖于scripts_basic scripts_dtc,现在查看scripts_dtc
? …
PHONY += scripts_dtc
scripts_dtc: scripts_basic
$(Q)$(MAKE) $(build)=scripts/dtc
? 执行make build=scripts/dtc,用于生成dtc工具,接下来分析asm-generic
? …
asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj
PHONY += asm-generic uapi-asm-generic
asm-generic: uapi-asm-generic
$(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/asm \
generic=include/asm-generic
uapi-asm-generic:
$(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/uapi/asm \
generic=include/uapi/asm-generic
? asm-generic为-f ./scripts/Makefile.asm-generic obj,asm-generic分支执行make -f ./scripts/Makefile.asm-generic obj=include/generated/asm generic=include/asm-generic,执行结果如下(uapi-asm-generic类似):
echo "#include <asm-generic/atomic.h>" > include/generated/asm/atomic.h
echo "#include <asm-generic/barrier.h>" > include/generated/asm/barrier.h
echo "#include <asm-generic/bitops.h>" > include/generated/asm/bitops.h
echo "#include <asm-generic/bug.h>" > include/generated/asm/bug.h
echo "#include <asm-generic/bugs.h>" > include/generated/asm/bugs.h
echo "#include <asm-generic/cacheflush.h>" > include/generated/asm/cacheflush.h
echo "#include <asm-generic/checksum.h>" > include/generated/asm/checksum.h
echo "#include <asm-generic/compat.h>" > include/generated/asm/compat.h
echo "#include <asm-generic/current.h>" > include/generated/asm/current.h
echo "#include <asm-generic/delay.h>" > include/generated/asm/delay.h
echo "#include <asm-generic/device.h>" > include/generated/asm/device.h
echo "#include <asm-generic/div64.h>" > include/generated/asm/div64.h
echo "#include <asm-generic/dma-contiguous.h>" > include/generated/asm/dma-contiguous.h
echo "#include <asm-generic/dma-mapping.h>" > include/generated/asm/dma-mapping.h
echo "#include <asm-generic/dma.h>" > include/generated/asm/dma.h
echo "#include <asm-generic/emergency-restart.h>" > include/generated/asm/emergency-restart.h
echo "#include <asm-generic/exec.h>" > include/generated/asm/exec.h
echo "#include <asm-generic/fb.h>" > include/generated/asm/fb.h
echo "#include <asm-generic/ftrace.h>" > include/generated/asm/ftrace.h
echo "#include <asm-generic/futex.h>" > include/generated/asm/futex.h
echo "#include <asm-generic/hardirq.h>" > include/generated/asm/hardirq.h
echo "#include <asm-generic/hw_irq.h>" > include/generated/asm/hw_irq.h
echo "#include <asm-generic/io.h>" > include/generated/asm/io.h
echo "#include <asm-generic/irq.h>" > include/generated/asm/irq.h
echo "#include <asm-generic/irq_regs.h>" > include/generated/asm/irq_regs.h
echo "#include <asm-generic/irq_work.h>" > include/generated/asm/irq_work.h
echo "#include <asm-generic/kdebug.h>" > include/generated/asm/kdebug.h
echo "#include <asm-generic/kmap_types.h>" > include/generated/asm/kmap_types.h
echo "#include <asm-generic/kprobes.h>" > include/generated/asm/kprobes.h
echo "#include <asm-generic/linkage.h>" > include/generated/asm/linkage.h
echo "#include <asm-generic/local.h>" > include/generated/asm/local.h
echo "#include <asm-generic/mm-arch-hooks.h>" > include/generated/asm/mm-arch-hooks.h
echo "#include <asm-generic/mmiowb.h>" > include/generated/asm/mmiowb.h
echo "#include <asm-generic/mmu.h>" > include/generated/asm/mmu.h
echo "#include <asm-generic/mmu_context.h>" > include/generated/asm/mmu_context.h
echo "#include <asm-generic/module.h>" > include/generated/asm/module.h
echo "#include <asm-generic/msi.h>" > include/generated/asm/msi.h
echo "#include <asm-generic/pci.h>" > include/generated/asm/pci.h
echo "#include <asm-generic/percpu.h>" > include/generated/asm/percpu.h
echo "#include <asm-generic/pgalloc.h>" > include/generated/asm/pgalloc.h
echo "#include <asm-generic/preempt.h>" > include/generated/asm/preempt.h
echo "#include <asm-generic/rwonce.h>" > include/generated/asm/rwonce.h
echo "#include <asm-generic/sections.h>" > include/generated/asm/sections.h
echo "#include <asm-generic/serial.h>" > include/generated/asm/serial.h
echo "#include <asm-generic/shmparam.h>" > include/generated/asm/shmparam.h
echo "#include <asm-generic/simd.h>" > include/generated/asm/simd.h
echo "#include <asm-generic/switch_to.h>" > include/generated/asm/switch_to.h
echo "#include <asm-generic/timex.h>" > include/generated/asm/timex.h
echo "#include <asm-generic/tlbflush.h>" > include/generated/asm/tlbflush.h
echo "#include <asm-generic/topology.h>" > include/generated/asm/topology.h
echo "#include <asm-generic/trace_clock.h>" > include/generated/asm/trace_clock.h
echo "#include <asm-generic/uaccess.h>" > include/generated/asm/uaccess.h
echo "#include <asm-generic/unaligned.h>" > include/generated/asm/unaligned.h
echo "#include <asm-generic/vermagic.h>" > include/generated/asm/vermagic.h
echo "#include <asm-generic/vga.h>" > include/generated/asm/vga.h
echo "#include <asm-generic/word-at-a-time.h>" > include/generated/asm/word-at-a-time.h
echo "#include <asm-generic/xor.h>" > include/generated/asm/xor.h
? 导入asm-generic头文件引用,到这里prepare0依赖解析完成(依赖部分生成的系统调用列表syscall table、编译部分工具、导入asm-generic头文件引用及检查一些需要用到的头文件),继续看prepare0
? …
prepare0: archprepare
1. $(Q)$(MAKE) $(build)=scripts/mod
2. $(Q)$(MAKE) $(build)=.
? 注意build,它是定义在文件scripts/Kbuild.include,内容为build := -f $(srctree)/scripts/Makefile.build obj;1.生成modpost和mk_elfconfig等工具;2.调用到根目录下Kbuild文件,如missing-syscalls:
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
? 现在prepare0解析完成,继续往下看
? …
$(build-dirs): prepare
$(Q)$(MAKE) $(build)=$@ \
single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) \
need-builtin=1 need-modorder=1
? 这里进入编译阶段,递归遍历从vmlinux-dirs以及它内部的全部目录执行make指令,build-dirs为init usr arch/x86 kernel certs mm fs ipc security crypto block drivers sound net virt arch/x86/power lib arch/x86/lib;所有的目录编译结束后,每个目录下的源代码将会被编译成.o文件并生成built-in.a
? …
tools/%: FORCE
$(Q)mkdir -p $(objtree)/tools
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $*
? 编译tools目录,执行DESCEND objtool
? …
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
+$(call if_changed,link-vmlinux)
? vmlinux依赖scripts/link-vmlinux.sh autoksyms_recursive(没有执行这个分支) $(vmlinux-deps),现在看下scripts/link-vmlinux.sh
? …
info LD vmlinux.o
modpost_link vmlinux.o
objtool_link vmlinux.o
? link-vmlinux.sh属于链接脚本,用于对象和库(.a)生成vmlinux静态可执行文件,生成System.map记录所有的链接符号,参考如下:
# vmlinux
# ^
# |
# +--< $(KBUILD_VMLINUX_OBJS)
# | +--< init/built-in.a drivers/built-in.a mm/built-in.a + more
# |
# +--< $(KBUILD_VMLINUX_LIBS)
# | +--< lib/lib.a + more
# |
# +-< ${kallsymso} (see description in KALLSYMS section)
#
...
info SYSMAP System.map
mksysmap vmlinux System.map
? …
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS)
? KBUILD_LDS为arch/x86/kernel/vmlinux.lds,KBUILD_VMLINUX_OBJS为arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/ebda.o arch/x86/kernel/platform-quirks.o init/built-in.a usr/built-in.a arch/x86/built-in.a kernel/built-in.a certs/built-in.a mm/built-in.a fs/built-in.a ipc/built-in.a security/built-in.a crypto/built-in.a block/built-in.a lib/built-in.a arch/x86/lib/built-in.a drivers/built-in.a sound/built-in.a net/built-in.a virt/built-in.a arch/x86/power/built-in.a,KBUILD_VMLINUX_LIBS为lib/lib.a arch/x86/lib/lib.a,这里是link-vmlinux.sh链接用到的文件,回到vmlinux
? …
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
+$(call if_changed,link-vmlinux)
? call if_changed,link-vmlinux执行后生成vmlinux和System.map
? …
VOFFSET arch/x86/boot/compressed/../voffset.h
CC arch/x86/boot/compressed/misc.o
OBJCOPY arch/x86/boot/compressed/vmlinux.bin
RELOCS arch/x86/boot/compressed/vmlinux.relocs
GZIP arch/x86/boot/compressed/vmlinux.bin.gz
MKPIGGY arch/x86/boot/compressed/piggy.S
AS arch/x86/boot/compressed/piggy.o
CC arch/x86/boot/compressed/kaslr.o
LD arch/x86/boot/compressed/vmlinux
ZOFFSET arch/x86/boot/zoffset.h
AS arch/x86/boot/header.o
CC arch/x86/boot/version.o
LD arch/x86/boot/setup.elf
OBJCOPY arch/x86/boot/setup.bin
OBJCOPY arch/x86/boot/vmlinux.bin
BUILD arch/x86/boot/bzImage
? 编译结果已经完成了,打开arch/x86/Makefile文件:
?
bzImage: vmlinux
...
1. $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
2. $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
3. $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
? 1.执行make -f scripts/Makefile.build obj=arch/x86/boot arch/x86/boot/bzImage,打开arch/x86/boot/Makefile对应代码:
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
@$(kecho) 'Kernel: $@ is ready' ' (#'`cat .version`')'
??? bzImage依赖于$(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build:
OBJCOPYFLAGS_setup.bin := -O binary
$(obj)/setup.bin: $(obj)/setup.elf FORCE
$(call if_changed,objcopy)
...
OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S
$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
$(call if_changed,objcopy)
??? 这两处是setup.bin和vmlinux.bin分支,build为arch/x86/boot/tools/build工具,最终生成bzImage
? 2.执行mkdir -p ./arch/x86/boot ? 3.执行ln -fsn …/…/x86/boot/bzImage ./arch/x86_64/boot/bzImage
|