ARM linux解析之zImage镜像文件的生成
_changed,objcopy)
@echo
到这里就可以知道了,哦,原来这个地方也是要vmlinux内核elf的啊,这就知道了,无论怎么样,vmlinux文件都要先生成,否则其他的文件都无法成生。下面来解释一下:
$(obj)/Image: vmlinux FORCE
$(call if_changed,objcopy)
@echo
这里的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 \
HEAD
OBJS
$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
$(obj)/piggy.$(suffix_y).o:
$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
插曲:关于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)),
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
$(obj)/piggy.$(suffix_y).o:
这里的suffix_y在,arch/arm/boot/compressed:
suffix_$(CONFIG_KERNEL_GZIP) = gzip
suffix_$(CONFIG_KERNEL_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文件生成的,内容如下:
input_data:
input_data_end:
可以看到压缩后的内核文件piggy.gzip是以bin文件的形式编译成piggy.gzip.o的,并且注意这里的是放在.piggydata段中的,这个在arch/arm/boot/compressed/vmlinux.lds指定
ARMlinuxzImage镜像文 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)