当编译linux的时候,运行make uImage,如果一切正常,最后会生成uImage。
如下具体讲解uImage生成过程:
1. 生成uImag的工具mkimage由arch/arm/boot/Makefile中的MKIMAGE定义.
Linux commit: e33936451 已经将此代码移到:<scripts/Makefile.lib>.
MKIMAGE := $(srctree)/scripts/mkuboot.sh
mkuboot.sh的作用是去找到是否存在"mkimage",此工具是用来生成最后的uImage。
mkuboot.sh 首先检查toolchain是否拥有mkimage (使用-z来判空),如果没有,再检查系统中是否拥有mkimage;如果没有则报错。
注:其中使用type命令来查找。
type: Display information about command type (type [-afptP] name [name ...])
==> # type mkimage
==> mkimage is /usr/bin/mkimage
然后调用:mkimage $@
2. 从makefile.boot中传入生成uImage的相关参数(e.g: arm/arm/mach-at91/Makefile.boot)
ifneq ($(MACHINE),) include $(srctree)/$(MACHINE)/Makefile.boot endif
3. 通过mkimage来生成uImage,其过程是加上0x40 bytes 的kernel头 on zImage.
Linux commit: e33936451 已经进行如下实现:
# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces # the number of overrides in arch makefiles UIMAGE_ARCH ?= $(SRCARCH) UIMAGE_COMPRESSION ?= $(if $(2),$(2),none) UIMAGE_OPTS-y ?= UIMAGE_TYPE ?= kernel UIMAGE_LOADADDR ?= arch_must_set_this UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR) UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)' UIMAGE_IN ?= $< UIMAGE_OUT ?= $@ quiet_cmd_uimage = UIMAGE $(UIMAGE_OUT) cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \ -C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \ -T $(UIMAGE_TYPE) \ -a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \ -n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)老版本如下:
quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel / -C none -a $(LOADADDR) -e $(STARTADDR) / -n 'Linux-$(KERNELRELEASE)' -d $< $@
mkimage的参数如下:
Usage: mkimage -l image -l ==> list image header information mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image -A ==> set architecture to 'arch' -O ==> set operating system to 'os' -T ==> set image type to 'type' -C ==> set compression type 'comp' -a ==> set load address to 'addr' (hex) -e ==> set entry point to 'ep' (hex) -n ==> set image name to 'name' -d ==> use image data from 'datafile' -x ==> set XIP (execute in place)
Load address 由下面代码获得
ifeq ($(CONFIG_ZBOOT_ROM),y) $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) else $(obj)/uImage: LOADADDR=$(ZRELADDR) endif
start address 由下面代码获得
$(obj)/uImage: STARTADDR=$(LOADADDR)
由zImage 生成uImage:
注:zImage的生成过程:http://blog.csdn.net/voice_shen/article/details/17713441
$(obj)/uImage: $(obj)/zImage FORCE $(call if_changed,uimage) @echo ' Image $@ is ready'
也可以自行用mkimage来生成uImage,
mkimage -A arm -O linux -T kernel -C none -a <load_addr> -e <entry_addr> -n <name> -d zImage uImage
e.g : mkimage -A arm -O linux -T kernel -C none -a 0x70008000 -e 0x70008000 -n linux-2.6.30 -d zImage uImage
其中:0x8000这32K 空间是:Note that the kernel uses 16K of RAM below the image to store page tables. The recommended placement is 32KiB into RAM. (来自Documentation/arm/booting文件)