Linux內核構建過程


構建內核

# shell 執行如下指令
make zImage

全局變量

srctree    := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
objtree    := $(CURDIR)
src        := $(srctree)
obj        := $(objtree)

VPATH      := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))

export srctree objtree VPATH

體系架構相關變量

ARCH        ?= arm
CROSS_COMPILE    ?= arm-linux-gnueabi-
# Architecture as present in compile.h
UTS_MACHINE     := $(ARCH)
SRCARCH     := $(ARCH)

編譯會用到的通用定義

# Look for make include files relative to root of kernel src
MAKEFLAGS += --include-dir=$(srctree)

# We need some generic definitions (do not try to remake the file).
$(srctree)/scripts/Kbuild.include: ;
include $(srctree)/scripts/Kbuild.include

引入體系結構相關 Makefile

# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
include $(srctree)/arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG KBUILD_KCONFIG

內核 vmlinux 鏡像布局

用於處理用戶直接在 shell 中輸入 make 這類操作,真正的目標是 all,此時僅生成 vmlinux

# That's our default target when none is given on the command line
PHONY := _all
_all:

vmlinux 依賴項

# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all
ifeq ($(KBUILD_EXTMOD),)
_all: all
else
_all: modules
endif
# 真正的目標
all: vmlinux

vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE

# head-y 對應的值 arch/arm/kernel/head.o arch/arm/kernel/init_task.o
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all  := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds
export KBUILD_VMLINUX_OBJS := $(vmlinux-all)

core-y        += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
init-y        := $(patsubst %/, %/built-in.o, $(init-y))
core-y        := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y    := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y        := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1        := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2        := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y        := $(libs-y1) $(libs-y2)

vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
             $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
             $(net-y) $(net-m) $(libs-y) $(libs-m)))

vmlinux-alldirs    := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
             $(init-n)
 $(init-) \
             $(core-n) $(core-) $(drivers-n) $(drivers-) \
             $(net-n)  $(net-)  $(libs-n)    $(libs-))))

# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# 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 version (uname -v) cannot be updated during normal
# descending-into-subdirs phase since we do not yet know if we need to
# update vmlinux.
# Therefore this step is delayed until just before final link of vmlinux -
# except in the kallsyms case where it is done just before adding the
# symbols to the kernel.
#
# System.map is generated to document addresses of all kernel symbols

生成 zImage

這其中給出了 make zImage 目標及其依賴

zImage Image xipImage bootpImage uImage: vmlinux
    $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

其作用是執行 arch/$(SRCARCH)/Makefile,傳入 MACHINE 參數,執行目標是 $(boot)/$@ --> arch/$(SRCARCH)/boot/zImage,查看 arch/arm/boot/Makefile

$(obj)/zImage:    $(obj)/compressed/vmlinux FORCE
    $(call if_changed,objcopy)
    @echo '  Kernel: $@ is ready'

$(obj)/Image: vmlinux FORCE
    $(call if_changed,objcopy)
    @echo '  Kernel: $@ is ready'

$(obj)/compressed/vmlinux: $(obj)/Image FORCE
    $(Q)$(MAKE) $(build)=$(obj)/compressed $@

該目標生成需要進入到 arch/arm/boot/compressed 下執行 make,使用 $(obj)/vmlinux.lds 鏈接腳本鏈接,head.o, piggy.o misc.o

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \
        $(addprefix $(obj)/, $(OBJS)) FORCE
    $(call if_changed,ld)
    @:

(obj)/vmlinux 的依賴目標,壓縮 boot 目錄下的 vmlinux 文件生成 piggy.gz,if_changed 執行的命令為 cmd_* 形式,定義在 Makefile.lib 中

$(obj)/piggy.gz: $(obj)/../Image FORCE
    $(call if_changed,gzip)

$(obj)/piggy.o:  $(obj)/piggy.gz FORCE

CFLAGS_font.o := -Dstatic=

$(obj)/font.c: $(FONTC)
    $(call cmd,shipped)
# 生成鏈接腳本
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
    @sed "$(SEDFLAGS)" < $< > $@

######################################################################
############# 最終,arch/arm/boot 目錄下生成 zImage...... ##############
######################################################################


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM