分类: LINUX
2010-11-26 16:51:09
uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。 mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么 zengxiaolong@zengxiaolong:~$ 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) zengxiaolong@zengxiaolong:~$ 参数说明: -A 指定CPU的体系结构: -------------------------------------------------------------- 取值 表示的体系结构 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 指定操作系统类型,可以取以下值: -------------------------------------------------------------- openbsd、netbsd、freebsd、4_4bsd、linux、svr4、esix、solaris、irix、sco、dell、ncr、lynxos、vxworks、psos、qnx、u-boot、rtems、artos -T 指定映象类型,可以取以下值: -------------------------------------------------------------- standalone、kernel、ramdisk、multi、firmware、script、filesystem -C 指定映象压缩方式,可以取以下值: -------------------------------------------------------------- none 不压缩 gzip 用gzip的压缩方式 bzip2 用bzip2的压缩方式 -a 指定映象在内存中的加载地址,映象下载到内存中时,要按照用mkimage制作映象时,这个参数所指定的地址值来下载 -e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个mkimage添加的0x40个字节的头) -n 指定映象名 -d 指定制作映象的源文件 ---------------------------------------------------- 1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。 2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm arg1这个指定的地址arg1是否与-a指定的加载地址相同,如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之。如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。 bootm arg1 arg2 arg1 uImage的下载地址 arg2 ramdisk.bin的下载地址 (initrd=arg2) 一般情况下uImage的下载地址(tftp的下载地址--arg1)和加载地址(-a参数地址)不同,ramdisk.bin的下载地址(tftp的下载地址--arg2)和加载地址(-a参数的地址 -- arg2)相同。还需要经过实践验证!!! ---------------------------------------------------- 1、用u-boot/tools/mkimage这个工具为你的内核加上u-boot引导所需要的文件头,具体做法如下: # mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage Image Name: linux-2.6.14 Created: Fri Jan 12 17:14:50 2007 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1262504 Bytes = 1232.91 kB = 1.20 MB Load Address: 0x30008000 Entry Point: 0x30008000 2 、下载内核 sbc2410=> tftp 0x31000000 uImage TFTP from server 192.168.1.115; our IP address is 192.168.1.128 Filename 'uImage'. Load address: 0x31000000 Loading: ################################################################# ################################################################# ################################################################# #################################################### done Bytes transferred = 1263324 (1346dc hex) 3.运行 sbc2410=>bootm 0x31000000 ## Booting image at 31000000 ... Image Name: linun-2.6.14 Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1263260 Bytes = 1.2 MB Load Address: 30008000 Entry Point: 30008000 Verifying Checksum ... OK OK ---------------------------------------------------- uImage的加载地址a与入口地址e为何相等? 如果uImage的下载地址不是0x30008000,两个入口地址就是一样的;如果uImage的下载是0x30008000,相对应的入口地址要增加0X40。 RAMDISK: Couldn't find valid RAM disk image starting at --------------------------------------------------------- ttyS00 at 0xe0005000 (irq = 24) is a 16450 NET4 RAMDISK: Couldn't find valid RAM disk image starting at 0. Freeing initrd memory: 2048K Kernel panic: VFS: Unable to mount root fs on 01:00 引导RAMFS方法 假设将文件系统下载到0x30300000. 用BOOTM引导内核和文件系统时,不仅需要将内核进行mkimage处理,文件系统也需要进行相应处理. 文件系统处理命令: mkimage -n "RAMFS" -A arm -O linux -T ramdisk -C none -a 30300000 -e 30300040 -d initrd.bin initrd.img 进行处理后,与内核处理结果相似,会在原来的文件系统映像前面加上一个64字节的头,这个头里包含了幻数,CRC校验信息和最重要的:文件系统起始地址和长度. 如果使用UBOOT引导内核,同时希望将文件系统一并引导,bootm命令后面需要跟两个参数,第一个参数是内核所在的地址,第二个参数是文件系统所在的位置,如bootm 30007fc0 30300000 上面说的引导文件系统是利用了bootloader向内核标准传参方法,如果已经在内核将诸如机器号,文件系统地址等全部写死的话,则不需要进行上述操作,只需将PC切换到内核所在地址就可以了. 用find和mkimage制作ramdisk.bin(原料是rootfs.tar.bz2) --------------------------------------------------------- find . | cpio -o -H newc | gzip > ../image.cpio.gz ./mkimage -T ramdisk -C gzip -n 'Ramdisk Image' -d image.cpio.gz ramdisk.bin |