uboot启动Linux内核


前言

参考文章:
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 
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值