文章目录
- 前言
- 1.uboot到Linux
- 2.vmlinuz、zImage、uImage、fit
- 3.启动细节
- 4.bootloader的启动方式发展
- 5.mkimage详解
前言
参考文章:
http://www.wowotech.net/u-boot/fit_image_overview.html
uboot文章连载:
1.uboot启动过程2.uboot命令体系3.uboot的环境变量4.uboot的驱动5.uboot启动Linux内核
Linux文章连载
前言:uboot启动过程
1.uboot到Linux
uboot帮助内核的两件事情:
1.uboot帮助内核实现重定位(从SD卡到DDR)
2.uboot给内核提供启动参数,并执行bootcmd命令启动内核
多种启动方式:
1.从SD卡的kernel分区去读取内核镜像到DDR:命令:movi read kernel 30008000。
2.tftp、nfs等网络下载方式从远端服务器获取镜像
uboot还支持远程启动:内核镜像放在主机的服务器中。
(注:镜像要放在DDR的链接地址处,链接地址去内核源代码的链接脚本或者Makefile中去查找。X210中是0x30008000。)
2.vmlinuz、zImage、uImage、fit
vmlinuz通过Linux压缩得到zImage,zImage通过uboot加头信息得到uImage
uboot中也可以支持zImage,是否支持就看x210_sd.h中是否定义LINUX_ZIMAGE_MAGIC这个宏。CONFIG_ZIMAGE_BOOT宏,用来支持zImage格式的内核启动。
编译内核得到uImage去启动:
如果直接在kernel底下去make uImage会提示mkimage command not found。解决方案是去uboot/tools下cp mkimage /usr/local/bin/,再去make uImage即可。
fit内核镜像树
以类似FDT的方式,将kernel、fdt、ramdisk等等镜像打包到一个image file中,并且加上一些需要的信息(属性)。uboot只要获得了这个image file,就可以得到kernel、fdt、ramdisk等等镜像的具体信息和内容。
3.启动细节
启动细节都在do_bootm中,其去判断是属于zImage、uImage、fit的哪种内核,再启动。
zImage,uImage,fit启动细节
没什么好讲的,看源码
do_bootm_linux函数
机器码的再次确定
(1)uboot在启动内核时,机器码要传给内核。uboot传给内核的机器码是怎么确定的?第一顺序备选是环境变量machid,第二顺序备选是gd->bd->bi_arch_num(x210_sd.h中硬编码配置的)
传参并启动概述
(1)从110行到144行就是uboot在给linux内核准备传递的参数处理。
(2)Starting kernel … 这个是uboot中最后一句打印出来的东西。这句如果能出现,说明uboot整个是成功的,也成功的加载了内核镜像,也校验通过了,也找到入口地址了,也试图去执行了。如果这句后串口就没输出了,说明内核并没有被成功执行。原因一般是:传参(80%)、内核在DDR中的加载地址·······
4.bootloader的启动方式发展
从u-boot的角度看,它要boot一个二进制文件(例如kernel Image),需要了解该文件的一些信息,例如:
该文件的类型,如kernel image、dtb文件、ramdisk image等等?
该文件需要放在memory的哪个位置(加载地址)?
该文件需要从memory哪个位置开始执行(执行地址)?
该文件是否有压缩?
该文件是否有一些完整性校验的信息(如CRC)?
device tree在ARM架构中普及之后,u-boot也马上跟进、大力支持,毕竟,美好的Unify kernel的理想,需要bootloader的成全。为了支持基于device tree的unify kernel,u-boot需要一种新的Image格式,这种格式需要具备如下能力:
1)Image中需要包含多个dtb文件。
2)可以方便的选择使用哪个dtb文件boot kernel。
其生成和使用过程为:
image source file mkimage + dtc transfer to target
+ -----------------------------> image file -----------------------------------> bootm
image data file(s)
its的语法:
image source file的语法和device tree source file完全一样(可参考[3][4][5]中的例子),只不过自定义了一些特有的节点,包括images、configurations等。说明如下:
1)images节点
指定所要包含的二进制文件,可以指定多种类型的多个文件,例如multi.its[5]中的包含了3个kernel image、2个ramdisk image、2个fdt image。每个文件都是images下的一个子node,例如:
kernel@2 {
description = "2.6.23-denx";
data = /incbin/("./2.6.23-denx.bin.gz");
type = "kernel";
arch = "ppc";
os = "linux";
compression = "gzip";
load = <00000000>;
entry = <00000000>;
hash@1 {
algo = "sha1";
};
};
可以包括如下的关键字:
description,描述,可以随便写;
data,二进制文件的路径,格式为----/incbin/(“path/to/data/file.bin”);
type,二进制文件的类型,“kernel”, “ramdisk”, "flat_dt"等,具体可参考中[6]的介绍;
arch,平台类型,“arm”, “i386”等,具体可参考中[6]的介绍;
os,操作系统类型,linux、vxworks等,具体可参考中[6]的介绍;
compression,二进制文件的压缩格式,u-boot会按照执行的格式解压;
load,二进制文件的加载位置,u-boot会把它copy对应的地址上;
entry,二进制文件入口地址,一般kernel Image需要提供,u-boot会跳转到该地址上执行;
hash,使用的数据校验算法。
2)configurations
可以将不同类型的二进制文件,根据不同的场景,组合起来,形成一个个的配置项,u-boot在boot的时候,以配置项为单位加载、执行,这样就可以根据不同的场景,方便的选择不同的配置,实现unify kernel目标。还以multi.its[5]为例,
configurations {
default = "config@1";
config@1 {
description = "tqm5200 vanilla-2.6.23 configuration";
kernel = "kernel@1";
ramdisk = "ramdisk@1";
fdt = "fdt@1";
};
config@2 {
description = "tqm5200s denx-2.6.23 configuration";
kernel = "kernel@2";
ramdisk = "ramdisk@1";
fdt = "fdt@2";
};
config@3 {
description = "tqm5200s denx-2.4.25 configuration";
kernel = "kernel@3";
ramdisk = "ramdisk@2";
};
};
它包含了3种配置,每种配置使用了不同的kernel、ramdisk和fdt,默认配置项由“default”指定,当然也可以在运行时指定。
image的编译和使用
FIT uImage的编译过程很简单,根据实际情况,编写image source file之后(假设名称为kernel_fdt.its),在命令行使用mkimage工具编译即可:
$ mkimage -f kernel_fdt.its kernel_fdt.itb
其中-f指定需要编译的source文件,并在后面指定需要生成的image文件(一般以.itb为后缀,例如kernel_fdt.itb)。
Image文件生成后,也可以使用mkimage命令查看它的信息:
$ mkimage -l kernel.itb
最后,我们可以使用dfu工具将生成的.idb文件,下载的memory的某个地址(没有特殊要求,例如0x100000),然后使用bootm命令即可启动,步骤包括:
1)使用iminfo命令,查看memory中存在的images和configurations。
2)使用bootm命令,执行默认配置,或者指定配置。
使用默认配置启动的话,可以直接使用bootm:
bootm 0x100000
选择其它配置的话,可以指定配置名:
bootm 0x100000#config@2
5.mkimage详解
mkimage作为uboo制作内核镜像的方式,其作用举足轻重,并且随着uboot加入了各种机制,其功能也变得复杂起来,其是在主机linux中使用的应用,在tools目录下,-h可以打印出其帮助文档:
root@ubuntu:/mnt/linuxshare/arm/uboot/tools# mkimage -h
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' // 镜像名称,注意不能超过32B
-d ==> use image data from 'datafile' // 输入文件
-x ==> set XIP (execute in place)
mkimage [-D dtc_options] -f fit-image.its fit-image
例子:
mkimage -A arm -O linux -C none -T kernel -a 0x20008000 -e 0x20008040 -n Linux_Image -d zImage uImage