由zImage生成uImage

简介: <div class="bct fc05 fc11 nbw-blog ztag"> <div id="content"> <div> <p style="text-indent:2em">内核编译(make):make menuconfig</p> <p style="text-indent:2em">make def</p> <p style="text-indent:2em"

内核编译(make):make menuconfig

make def

make

 

内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。

    那么uImage又是什么的?它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别。

     如 何生成uImage文件?首先在uboot的/tools目录下寻找mkimage文件,把其copy到系统/usr/local/bin目录下,这样就 完成制作工具。然后在内核目录下运行make uImage,如果成功,便可以在arch/arm/boot/目录下发现uImage文件,其大小比 zImage多64个字节。

其实就是一个自动跟手动的区别,有了uImage头部的描述,u-boot就知道对应Image的信息,如果没有头部则需要自己手动去搞那些参数。

U-boot的U是“通用”的意思。

zImage 是ARM Linux常用的一种压缩映像文件,uImage是U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的“头”,说明 这个映像文件的类型、加载位置、生成时间、大小等信息。换句话说,如果直接从uImage的0x40位置开始执行,zImage和uImage没有任何区 别。另外,Linux2.4内核不支持uImage,Linux2.6内核加入了很多对嵌入式系统的支持,但是uImage的生成也需要设置。

 

如何生成 uImage

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 。

相关文章
|
存储 开发框架 缓存
WKWebView 原生与JavaScript交互方法
WKWebView 原生与JavaScript交互方法
1206 0
WKWebView 原生与JavaScript交互方法
|
人工智能 vr&ar
TRELLIS:微软联合清华和中科大推出的高质量 3D 生成模型,支持局部控制和多种输出格式
TRELLIS 是由微软、清华大学和中国科学技术大学联合推出的高质量 3D 生成模型,能够根据文本或图像提示生成多样化的 3D 资产,支持多种输出格式和灵活编辑。
1670 3
TRELLIS:微软联合清华和中科大推出的高质量 3D 生成模型,支持局部控制和多种输出格式
|
编解码 网络协议 编译器
QT软件开发: 基于FFMPGE设计的流媒体播放器(rtmp/rtsp)
QT软件开发: 基于FFMPGE设计的流媒体播放器(rtmp/rtsp)
1544 0
QT软件开发: 基于FFMPGE设计的流媒体播放器(rtmp/rtsp)
|
存储 安全 数据安全/隐私保护
|
传感器 监控
基于STM32的智能交通灯控制系统设计与实现
基于STM32的智能交通灯控制系统设计与实现
1814 0
|
人工智能 编解码 文字识别
阿里国际AI开源Ovis1.6,多项得分超GPT-4o-mini!
阿里国际AI团队提出了一种名为Ovis (Open VISion)的新型多模态大模型的架构。
|
缓存 前端开发 JavaScript
换肤 - 一文看破常用的网站主题切换方式
现在大部分主流网站都不约而同的添加了暗色主题,让我们一起看看这些常用的切换方案、实现方式以及注意点。
|
Web App开发 应用服务中间件 网络安全
nginx强制使用https访问(http跳转到https
   需求简介 基于nginx搭建了一个https访问的虚拟主机,监听的域名是test.com,但是很多用户不清楚https和http的区别,会很容易敲成http://test.com,这时会报出404错误,所以我需要做基于test.
7421 0
|
云安全 存储 运维
首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题
从“上云”到“云上”原生,云原生提供了最优用云路径,云原生的技术价值已被广泛认可。当前行业用户全面转型云原生已是大势所趋,用户侧云原生平台建设和应用云原生化改造进程正在加速。
3899 120
首次全面解析云原生成熟度模型:解决企业「诊断难、规划难、选型难」问题
|
机器学习/深度学习 数据采集 数据可视化
利用Python进行历史数据预测:从入门到实践的两个案例分析
利用Python进行历史数据预测:从入门到实践的两个案例分析
1366 1

热门文章

最新文章