一、Image、zImage和uImage的区别
内核编译(make)之后会生成两个文件,一个是Image,一个是zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。uImage是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没什么区别。uImage的64字节的头结构如下:
typedef struct image_header{
uint32_tih_magic;
uint32_tih_hcrc;
uint32_tih_time;
uint32_tih_size;
uint32_tih_load;
uint32_tih_ep;
uint32_tih_dcrc;
uint32_tih_os;
uint32_tih_arch;
uint32_tih_type;
uint32_tih_comp;
uint32_tih_name[IH_NMLEN];
}image_header_t;
所以uImage和zImage都是压缩后的内核映像,而uImage是uboot专用的映像文件,是用mkimage工具根据zImage制作而来的。
二、uImage的制作
mkimage工具
内核编译完后zImage在内核根目录下,mkimage工具在u-boot根目录下的tools文件夹中,将zImage和mkimage放在同一个目录下,执行:
./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008000 -n linux-2.6.26 -d zImage uImage2.6.26
就将zImage转换成uImage了。
【mkimage的命令参数:】
-A :==>set architecture to ‘arch’:用于指定CPU类型,比如arm、x86、mips、ppc
-O :==>set operating system to ‘os’:用于指定操作系统,比如freebsd、linux、vxworks
-T :==>set image type to ‘type’:用于指定image类型,比如kernel、ramdisk、filesystem
-C :==>set compression type ‘comp’:用于指定压缩类型:none、gzip、bzip2
-a :==>set load address to ‘addr’(hex):用于指定uImage的加载地址
-e :==>set entry point to ‘ep’(hex):用于指定内核的入口地址,一般是:uImage的载入地址+0x40(信息头的大小)
-n :==>set image name to ‘name’:用于指定uImage在头结构中的命名
-d :==>use image data from ‘datafile’:用于指定无头信息的zImage文件名
-x :==>set XIP(execute in place):用于设置执行位置
如对于ARM Linux内核映像常用选项为:
-A arm :==>架构是arm
-O linux :==>操作系统是linux
-T kernel :==>类型是kernel
-C none/bzip/gzip :==>压缩类型
-a 0x40008000 :==> uImage的载入地址(hex),通常为0xX0008000
-e 0x40008040 :==>内核的入口地址(hex),XX为0x40或者0x00
-n linux-xxx :==> uImage的名字,任意
-d namexxx :==>无头信息的zImage文件名,为源内核文件
uImagexxx :==>加了头信息之后的zImage文件名,任意
【例子:】
./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -d zImage uImage
【注意:】
-a和-e后面跟的分别是image的载入地址和内核的入口地址,两者可以一样,也可以不一样,依据如下情况而定:
当-a后面指定的地址和bootm xxxx后面的地址一样时,-e后面的地址必须要比-a后面的地址多0x40,也就是映像头的大小64个字节。因为当他们地址一样时,uboot是不会搬运映像的;
当-a后面指定的地址和bootm xxxx后面的地址不一样时,uboot会将bootm xxxx地址处的映像文件搬运到-a指定的地址处,此时,-e和-a必须要一样,因为映像头并没有搬运过去,载入地址就是内核的入口地址。需要注意的是,因为uboot要重新搬运内核映像,所以要注意bootm xxxx的地址和-a之间的地址不要导致复制时的覆盖。