由zImage生成uImage

mkimage -A arm -O linux -T kernel -C none -a 30007fc0 -e 30007fc0 -n uImage   -d /work/jz2440/kernel/linux-2.6.22.6/arch/arm/boot/zImage uImage

我的内核目录:/work/jz2440/kernel/linux-2.6.22.6


我的tftpboot:/work/tftpbootuboot——bootm地址:30007fc0

名字:uImage

需要先安装mkimage工具
----------------------------------------------------------------------------------------

参考:http://blog.sina.com.cn/s/blog_7776b9d301017pck.html

U-boot 就是为加载kernel而服务的
简单来讲:u-boot 启动过程分为两个部分 :Stage 1 and Stage2
Stage1 主要是初始化硬件设备, 然后最主要的功能就是把Stage2 load到RAM中去。

u-boot与kernel的关系

U-boot为kernel服务, u-boot为kernel提供一些kernel无法知道的信息,比如ramdisk在RAM中的地址
Kernel也必须为U-boot提供必要的信息:通过mkimage这个tool可以给zImage添加一个header:
typedef struct image_header {
 uint32_t ih_magic;
 uint32_t ih_hcrc;
 uint32_t ih_time;
 uint32_t ih_size;
 uint32_t ih_load;
 uint32_t ih_ep;  
 uint32_t ih_dcrc;
 uint8_t  ih_os;  
 uint8_t  ih_arch;
 uint8_t  ih_type;
 uint8_t  ih_comp;
 uint8_t  ih_name[IH_NMLEN];
} image_header_t;

利用u-boot里面的mkimage工具来生成uImage   (u-boot源码包/tools/mkimage.c )
用法:
    -A arm     -------- 架构是arm-O linux    -------- 操作系统是linux-T kernel  -------- 类型是kernel-C none    -------- 压缩类型为无压缩-a 30008000 ---- image的载入地址(hex)-e 30008040 ---- 内核的入口地址(hex),因为信息头的大小是0x40-n linux-2.6.18.8 --- image的名字-d zImage             ---- 无头信息的image文件名uImage2.6. 18.8    ---- 加了头信息之后的image文件名

生成uImage 的方法
 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
注释:这里的意思就是把zImage的前面加上一个0x40长度的header ,没有压缩(none) , kernel的load地址是:-a 30008000   ; kernel的入口地址是 –e 30008000
不知道是否对入口地址有疑问:为什么入口地址不是 0x80003040 呢?  答案就在 u-boot 里面的bootm命令的实现代码上, 我会在 “分析bootm源码”中给予分析介绍 , 来详细分析
1> mkimage 如何指定入口参数 ( -e  0xxxxxx)
2> mkimage 指定了入口参数后, 你用tftpboot 下载kernel到哪个地址?

#/usr/local/src/u-boot-1.2.0/tools/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

imagefile = uImage2.6.18.8
Image Name:   linux-2.6.18.8
Created:      Fri Jun 15 13:56:06 2007
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    1068212 Bytes = 1043.18 kB = 1.02 MB
Load Address: 0x30008000
Entry Point:  0x30008000

生成uImage的方法: 利用mkimage 命令 把zImage 包装 , 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 下面的总结都是 稍微调整一下上面的 -a -e -x 参数什么的, 你会发现这些参数不同, 就会导致你 tftp dowload的地址会有不同, 有的时候kernel会run不起来。

addr是地址 , 如果两个地方都是addr ,说明是同一个地址, 否则 我会比如addr+0x40 的 1> mkimage -a addr -e addr 那么tftp 下载kernel 就一定不能下载 addr处 , 否则,kernelrun不起来。 因为u-boot并不搬运kernel 代码,也就是没有把header去掉。所以只有入口是 addr+0x40才是kernel的入口。 当然也不能下到 < addr + 2M 的地方,否则搬运的时候会有一些覆盖, 导致搬运后的kernel不完整, bootm的时候,u-boot就会RESET 的。

2> mkimage -a addr -e addr+0x40 或者 mkimage -a addr -x 两个是一回事 。 -x的意思 是就在kernel所在地执行。 不必搬运(代码里面的条件是 tftp 下kernel的时候 就下到 addr处,这样bootm就没有必要搬运了) 这种情况: tftp 就一定把kernel 下载到addr处 ,这样u-boot 在bootm的时候 就不搬运了。 其实这种情况更多的用在flash里面 。 //  -----------------------------------------------------
 switch (hdr->ih_comp) {
 case IH_COMP_NONE:  // -C none
  if(ntohl(hdr->ih_load) == addr) { //不搬运
   printf (“   XIP %s ... ”, name);//注意屏幕信息
  } else {
   memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);   //搬运:这里data指向实际的kernel ,把kernel搬运到hdr->ih_load处,这个值就是mkimage –d 0x30008000
  }

对于u-boot最常用得命令莫过于:
tftpboot 和 bootm 命令了。
具体分析一下这两个过程,这样大家用的时候就知其所以然了,也就能少犯一些错误了。具体参考:common/cmd_bootm.c  ? do_bootm()
还有do_bootm_linux() 函数
比如 :
Tftpboot 0x3300,0000  uImage
Tftpboot 0x3080,0000  ramdisk.gz
Bootm 0x3300,0000  0x3080,0000

过程:tftpboot把uImage 下载地址0x33000000 ,然后把ramdisk.gz 下载到0x30800000 .
最后执行bootm ,
Bootm  会首先取出uImage的0x40个header ,然后读取header的ih_load字段,
只有这样u-boot 才知道把uImage搬运到哪里。  
在中间的时候, u-boot 会判断tftp 下载kernel的地址是否等于ih_load ,这里非常关键。如果等于就不搬运;如果不等于u-boot 把指针定位到0x40之后的位置, 这里才是真正的kernel(zImage), 把zImage 搬运(copy)到  ih_load这个地址上去。 然后执行kernel 。

时间: 2024-10-11 01:59:47

由zImage生成uImage的相关文章

zImage与uImage的区别

zImage: vmlinux是内核文件,zImage是一般情况下默认的压缩内核映像文件,压缩vmlinux,加上一段解压启动代码得到. uImage: uImage则是使用工具mkimage对普通的压缩内核映像文件(zImage)加工而得.它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本.加载位置.生成时间.大小等信息.其0x40之后与zImage没区别. 有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需

第一次生成uImage出现的问题解决

内核移植(1)首次生成uImage映象文件 1.先修改顶层Makefile,如下: ARCH                     ?= $ (SUBARCH) CROSS_COMPILE      ?= 改为: ARCH                     ?= arm CROSS_COMPILE      ?=  arm-linux- 2.执行make s3c2410_defconfig 3.make uImage,首次编译完内核用了4分钟,尾部出现如下信息: LD      arch

zImage转换为uImage

写个随笔,备忘! 拿到一个内核后,首先将其make为zImage,步骤: 1.将与要移植的系统的配置文件拷贝给.config cp xxx_xxx .config 2.修改Makefile,指定平台构架和交叉编译环境 vim Makefile  ARCH  ?=XXX CROSS_COMPILE ?=xxxx 3.启动配置界面,定制内核 make nemuconfig 4.make zImage, 内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像

【linux内核编译】Image、zImage、uImage的区别和联系

Image:内核映像文件,大约为4M: zImage:内核的一种映像压缩文件,不到2M: 内核编译(make)之后会生成Image和zImage: uImage:uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本.加载位置.生成时间.大小等信息,在0x40之后与zImage没有任何区别: uImage文件的生成方式: 1.在uboot的/tools目录下寻找mkimage文件,把其copy到系统/usr/local/bin目录下,这样就完成制作工具

zImage和uImage的区别

http://blog.csdn.net/maojudong/article/details/4178118 zImage和uImage的区别 一.vmlinuz vmlinuz是可引导的.压缩的内核.“vm”代表“Virtual Memory”.Linux 支持虚拟内存,不像老的操作系统比如DOS有640KB内存的限制.Linux能够使用硬盘空间作为虚拟内存,因此得名“vm”. vmlinuz 的建立有两种方式.一是编译内核时通过“make zImage”创建,然后通过:“cp /usr/sr

编译内核无法生成uImage的原因分析

uBoot启动内核,需要符合要求的内核镜像文件uImage(包含head+body组成): 内核镜像需要mkimage来制作: 如果shell在环境变量目录中找不到mkimage工具,就无法生成uImage: 这里的mkimage必须是编译uboot源码后,在/uboot/tools下面生成的工具mkimage. 所以解决办法就是: 第一步:编译uboot,这时将会在uboot/tools下生成mkimage工具: 第二步:声明环境变量,在/etc/bash.bashrc中添加如下语句: exp

Image zImage uImage

内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M. 那么uImage又是什么的?它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本.加载位置.生成时间.大小等信息:其0x40之后与zImage没区别. 如何生成uImage文件?首先在uboot的/tools目录下寻找mkimage文件,把其copy到系统/

uImage、zImage、bzImage、vlinzx区别

在网络中,不少服务器采用的是Linux系统.为了进一步提高服务器的性能,可能需要根 据特定的硬件及需求重新编译Linux内核.编译Linux 内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要的文件.比如对于RedHat Linux,在/boot目录下有一些与Linux内核有关的文件 . 编译过RedHat Linux内核的人对其中的System.map.vmlinuz.initrd-2.4.7-10.img印象可能比较深刻,因为编译内核过程中涉及到这些文件的建立等操作.那么这几个文件是

uImage、zImage、bzImage、vlinzx区别(转)

在网络中,不少服务器采用的是Linux系统.为了进一步提高服务器的性能,可能需要根据特定的硬件及需求重新编译Linux内核.编译Linux 内核,需要根据规定的步骤进行,编译内核过程中涉及到几个重要的文件.比如对于RedHat Linux,在/boot目录下有一些与Linux内核有关的文件 . 编译过RedHat Linux内核的人对其中的System.map.vmlinuz.initrd-2.4.7-10.img印象可能比较深刻,因为编译内核过程中涉及到这些文件的建立等操作.那么这几个文件是怎