我们知道,通过make 或者 make linux可以生成我们需要的linux内核映像。该映像文件是非压缩的bin格式,可以直接运行在ram中,调试程序。然而当我们的内核和程序都调试完毕,必须发布的时候,通常应该采用压缩内核发布到flash中。压缩内核运行后,使用头部的自解压程序把自己解压到ram中。
那些文件影响zImage文件的生成呢?
zImage
自解压程序misc.o
压缩内核piggy.o
未压缩内核linux
ZTEXTADDR
ZRELADDR
1。arch/armnommu/boot/Makefile文件:
ifeq ($(CONFIG_BOARD_MBA44),y)
ZRELADDR = 0x0c008000 //解压后的内核运行地址
ZTEXTADDR = 0x0c480000 //未解压的内核存放的地址
endif
zImage: $(CONFIGURE) compressed/$(LINUX)
$(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@
zImage实际上是通过把boot/compressed/linux重新格式输出的。那compressed/linux是如何生成的呢?和src/linux有什么联系呢?
2。查看arch/armnommu/boot/compressed目录
#
# linux/arch/arm/boot/compressed/Makefile
#
# create a compressed vmlinuz image from the original vmlinux
#
# Note! SYSTEM, ZTEXTADDR, ZBSSADDR and ZRELADDR are now exported
# from arch/arm/boot/Makefile
#
HEAD = head.o //内核的头部,完成CPU的初始化等
OBJS = misc.o //也位于内核的头部,完成对内核的自解压
CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_PROC) -msoft-float -D__linux__
FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c
ZLDFLAGS = -p -X -T $(LINUX).lds
#
# Architecture dependencies
#
省略掉:)
SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;
ifneq ($(ZBSSADDR),)
SEDFLAGS += s/BSS_START/$(ZBSSADDR)/
else
SEDFLAGS += s/BSS_START/ALIGN(4)/
endif
all: $(LINUX)
$(LINUX): $(HEAD) $(OBJS) piggy.o $(LINUX).lds
$(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o -o $(LINUX)
既然zImage是由$(LINUX)重新格式输出的。那么我们可以看到linux由head.o,misc.o,piggy.o组成。linux.lds是连接脚本文件,有LD使用。
$(HEAD): $(HEAD:.o=.S)
$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
head.o由head.S生成。Head.S中调用decompress_kernel解压内核。
piggy.o: $(SYSTEM)
$(OBJCOPY) -O binary -R .note -R .comment -S $(SYSTEM) piggy
gzip $(GZFLAGS) < piggy > piggy.gz
$(LD) -r -o $@ -b binary piggy.gz
rm -f piggy piggy.gz
piggy.o是核心所在!他是通过把未压缩的内核映像格式化输出为piggy文件。然后将piggy用zip压缩为piggy.gz。最后使用LD把piggy.gz格式为binary的piggy.o文件。
font.o: $(FONTC)
$(CC) $(CFLAGS) -Dstatic= -c -o $@ $(FONTC)
$(LINUX).lds: $(LINUX).lds.in
sed "$(SEDFLAGS)" < $(LINUX).lds.in > $@
linux.lds文件,是由linux.lds.in文件格式输出来的。SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;因此修改linux.lds.in和本文件中的ZTEXTADDR、ZRELADDR变量即可。
clean:; rm -f $(LINUX) core piggy* $(LINUX).lds
.PHONY: $(LINUX).lds clean
misc.o: misc.c $(TOPDIR)/include/asm/arch/uncompress.h $(TOPDIR)/lib/inflate.c
misc.o完成了对内核的解压。他由misc.c include/asm/arch/uncompress.h lib/inflate.c编译而来。Misc.c实现decompress_kernel函数体。
而对于串口的初始化程序代码,以及最为底层的串口输出函数的实现也是由uncompress完成的。
Inflate.c函数完成gunzip的实现。