IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> linux内核make执行过程 -> 正文阅读

[系统运维]linux内核make执行过程

本篇基于上一篇<<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

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-14 21:37:00  更:2022-02-14 21:38:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:45:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码