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

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

时间:11-11 来源:互联网 点击:

_changed,objcopy)

@echo Kernel: $@ is ready

到这里就可以知道了,哦,原来这个地方也是要vmlinux内核elf的啊,这就知道了,无论怎么样,vmlinux文件都要先生成,否则其他的文件都无法成生。下面来解释一下:

$(obj)/Image: vmlinux FORCE

$(call if_changed,objcopy)

@echo Kernel: $@ is ready

这里的Image也就是linux_src/arch/arm/boot/Image,它的生成是通过把linux_src/vmlinux这个elf文件用通过objcopy生成bin文件Image。然后:

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

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

这句和上面分析的类似,就是进入linux_src/arch/arm/boot/compress/mafile中生成:

arch/arm/boot/compress/vmlinux文件,如下:

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \

$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE

$(call if_changed,ld)

@$(check_for_bad_syms)

HEAD= head.o

OBJS+= misc.o decompress.o

$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE

$(call if_changed,$(suffix_y))

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

$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)

@sed "$(SEDFLAGS)" < $< > $@

插曲:关于if_changed的解释:

Kbuild.include:

# >< substitution is for echo to work,

# >$< substitution to preserve $ when reloading .cmd file

# note: when using inline perl scripts [perl -e ...$$t=1;...]

# in $(cmd_xxx) double $$ your perl vars

make-cmd= $(subst \\,\\\\,$(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))))

# Find any prerequisites that is newer than target or that does not exist.

# PHONY targets skipped in both cases.

any-prereq= $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)

# 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)

if_changed函数在当发现规则的依赖有更新,或是目依赖不存在时,再或者是对应目标的命令行参数发生改变时($(strip $(any-prereq) $(arg-check))语句结果不为空),执行后面的语句。

set -e表示如果命令执行有错那么命令停止执行并退出。

接着$(echo-cmd)用来打印出相关的编译命令,接着执行$(cmd_$(1)里的命令。

最后echo cmd_$@ := $(make-cmd) > $(dot-target).cmd将上面执行的命令写入一个叫$(dot-target).cmd的文件中,该文件为隐藏文件,在编译后的内核源码目录及其子目录下随处可见,比如在init/下可以看到.initramfs.o.cmd,.version.o.cmd等等。

那么而所有的命令测存在呢?答案是:scripts/Makefile.lib:

scripts/Makefile.build里面:include scripts/Makefile.lib

scripts/Makefile.lib:

# Objcopy

# ---------------------------------------------------------------------------

quiet_cmd_objcopy= OBJCOPY$@

cmd_objcopy= $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@

# Gzip

# ---------------------------------------------------------------------------

quiet_cmd_gzip= GZIP$@

cmd_gzip= (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || (rm -f $@ ; false)

言归正传,回到上面:

$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE

$(call if_changed,$(suffix_y))

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

这里的suffix_y在,arch/arm/boot/compressed:

suffix_$(CONFIG_KERNEL_GZIP) = gzip

suffix_$(CONFIG_KERNEL_LZO)= lzo

suffix_$(CONFIG_KERNEL_LZMA) = lzma

CONFIG_KERNEL_GZIP=y是在init/Kconfig文件里选择的,menuconfig时配置,我们这里选gzip,则上面的过程为

使用gzip对arch/arm/boot/Image文件进行压缩,压缩成piggy.gzip。然后再生成piggy.gzip.o:

这个是通过piggy.gzip.S文件生成的,内容如下:

.section.piggydata,#alloc

.globlinput_data

input_data:

.incbin"arch/arm/boot/compressed/piggy.gzip"

.globlinput_data_end

input_data_end:

可以看到压缩后的内核文件piggy.gzip是以bin文件的形式编译成piggy.gzip.o的,并且注意这里的是放在.piggydata段中的,这个在arch/arm/boot/compressed/vmlinux.lds指定

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

网站地图

Top