uImage的制作是使用的u-boot工具mkimage,build完u-boot后也会将mkimage build出來到/tools目录下,可以直接拿來用,它的作用就是在zImage的前面加上64个字节的头,让u-boot能够识别要加载内核的类型、加载地址等。
基本格式:mkimage -n 'linux-3.4.2' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage uImage
-A 指定CPU的体系结构:(u-boot支持多种的架构,这里应该是arm)
取值 表示的体系结构
alpha Alpha
arm A RM
x86 Intel x86
ia64 IA64
mips MIPS
mips64 MIPS 64 Bit
ppc PowerPC
s390 IBM S390
sh SuperH
sparc SPARC
sparc64 SPARC 64 Bit
m68k MC68000
-O 指定操作系统类型,可以取以下值:(u-boot支持多种的OS,这里应该是linux)
openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos
-T 指定映象类型,可以取以下值:(u-boot可以加载不同的映像,这里应该是kernel)
standalone、kernel、ramdisk、multi、firmware、script、filesystem
-C 指定映象压缩方式,可以取以下值:(除了zImage本身是压缩格式外,u-boot还可以对其再压缩,这里应该是none)
none 不压缩
gzip 用gzip的压缩方式
bzip2 用bzip2的压缩方式
-a 指定映象在内存中的加载地址,可以于实际加载(如tftp加载)时的地址不相同,也可以相同,详见后面的解释。
-e 指定映像运行的入口地址,可以等于加载地址,也可以是加载地址偏移64字节(+0x40)后的地址,详见后面的解释。
-n 指定映像名称
-d 指定【源文件】和生成的【目标文件名】
所以如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址是否相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。
我们来看看这三个地址的不同情况:
1> mkimage -A arm -O linux -T kernel -C none -a 30008000 -e
30008040 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8040
这种情况 ,只能把 uImage download到 30008000的位置上,否则 从 30008040
是启动不了的。
原因:如果将uImage(加了头的镜像文件)下载到不同于指定加载地址的地方,则会进行上面的操作,将去掉头部的内核拷贝到指定的加载地址,此时加载地址和入口地址需要是相同的,因为已经没有镜像头了,所以此时入口地址也应该为30008000,而不应该再加上64个字节
所以在构建镜像头部中的加载地址和入口地址时千万要考虑下载的地址,否则将会启动不了。
2> mkimage -A arm -O linux -T kernel -C none -a 30008000 -e
30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8000
这种情况download地址随便。 还是按上面说的,因为将加载地址和入口地址设置成同样的地址,在下载到任意地址时,将去掉头部的内核镜像拷贝到指定加载地址后,可以直接从加载地址开始启动。但是要是下载地址和指定加载地址相同呢?也就是下面的:
如果 tftp 下载地址==0x30008000 , 此时因为下载地址和指定加载地址相同,所以就不会搬动,内核直接从指定加载地址自解压啦,但是因为指定的入口地址也是0x30008000,还是在镜像头处,可以看到上面的代码,如果相同没有做任何事,只是打印了提示信息,所以还得将入口地址往后推后64个字节还是从 0x30008040 启动就肯定OK 。
所以在制作镜像头以及下载地址就有两种情况:
1,mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img
加载地址和入口地址相同
tftp 0x31000000 zImage.img
bootm 0x31000000
下载地址可以任意放。
2,mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
入口地址在加载地址后面64个字节
tftp 0x30008000 zImage.img
bootm 0x30008000
下载地址一定要在指定的加载地址上。