微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM linux解析之zImage镜像文件的生成

ARM linux解析之zImage镜像文件的生成

时间:11-11 来源:互联网 点击:
最开始做个约定:存放linux代码的根目录我们叫做:linux_src,代码用linux-3.0.46进行分析。对于arm系统,$(SRCARCH) = ARM

可能你会想,究竟linux如何编译生成它的压缩内核镜像zImage的呢?哈哈,下面就来做个解析。

当我们在linux_src目录下输入命令:

> make zImage

就会进入linux_src/makfile,然后找zImage目标,这个目标在:

linux_src/makfile包含的:include $(srctree)/arch/$(SRCARCH)/Makefile里面,

位于:linux_src/arch/arm/makfile里:

zImage Image xipImage bootpImage uImage: vmlinux

$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

可以看到zImage依赖于vmlinux,这里的vmlinux指的是linux_src/vmlinux,这是编译生成的linux内核的elf文件。那么vmlinux又是在哪生成的呢?请向下看:

它的生成规则在linux_src/makefile文件中,如下:

#vmlinux image - including updated kernel symbols

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

ifdef CONFIG_HEADERS_CHECK

$(Q)$(MAKE) -f $(srctree)/Makefile headers_check

endif

ifdef CONFIG_SAMPLES

$(Q)$(MAKE) $(build)=samples

endif

ifdef CONFIG_BUILD_DOCSRC

$(Q)$(MAKE) $(build)=Documentation

endif

$(call vmlinux-modpost)

$(call if_changed_rule,vmlinux__)

$(Q)rm -f .old_version

vmlinux的生成依赖于:$(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o),同样在linux_src/makefile文件中:

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

modpost-init := $(filter-out init/built-in.o, $(vmlinux-init))

vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE

$(call if_changed_rule,vmlinux-modpost)

kallsyms.o:= .tmp_kallsyms$(last_kallsyms).o

这里可以看到vmlinux就是由这些依赖文件通过arch/$(SRCARCH)/kernel/vmlinux.lds链接生成的,我就不再每往下解释了。

生成了linux_src/vmlinux之后,再回头看arch/arm/boot/compressed/Makefile文件中的:

zImage Image xipImage bootpImage uImage: vmlinux

$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@

其中$(build)在linux_src/scripts/kbuild.include:

###

# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=

# Usage:

# $(Q)$(MAKE) $(build)=dir

build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj

因为KBUILD_SRC为空,srctree就是当前目录,故
build := -f ./scripts/Makefile.build obj

boot := arch/arm/boot

ifneq ($(machine-y),)

MACHINE:= arch/arm/mach-$(word 1,$(machine-y))/

else

MACHINE:=

endif

machine-$(CONFIG_ARCH_EVB_ARM):= evb_arm

Kconfig中:CONFIG_ARCH_EVB_ARM = y

所以对于我们的平台:

MACHINE:= arch/arm/mach-evb_arm

最开始的那一句最终解释为:

zImage:vmlinux

@make –f./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-evb_armarch/arm/boot/zImage

下面就是进入到linux_src/scripts/Makefile.build这个makefile文件中

src := $(obj)

kbuild-dir:= $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

kbuild-file:= $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)

include$(kbuild-file)

在这里:

src:= $(obj) :=arch/arm/boot//这个就是上一个makefile传下来的值

kbuild-dir:= $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

//这句的意思是,如果src是以/开头的,则kbuild-dir :=$(src),

如果不是的就等于kbuild-dir :=$(srctree)/$(src)

这里kbuild-dir:= ./arm/arm/boot

kbuild-file :=./arch/arm/boot/Kbuild ./arch/arm/boot/Makefile

最后一句:

include ./arch/arm/boot/Kbuild ./arch/arm/boot/Makefile

可以看到这里是要包含linux_src/arch/arm/boot/Makefile文件,果然在里面找到了我们要的目标:

$(obj)/zImage:$(obj)/compressed/vmlinux FORCE

$(call if_changed,objcopy)

@echo Kernel: $@ is ready

再找$(obj)/compressed/vmlinux:

$(obj)/compressed/vmlinux: $(obj)/Image FORCE

$(Q)$(MAKE) $(build)=$(obj)/compressed $@

再接着找$(obj)/Image:

$(obj)/Image: vmlinux FORCE

$(call if

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top