ARM uboot Legacy uImage 和 fit img (Flattened uImage Tree)原理介绍

一、先谈谈uboot

uboot 是嵌入式领域中用到的操作系统内核引导工具。
因为嵌入式发展相对pc 领域要慢一点。所以我一般会把uboot当成是一个落后一点迷你一点的grub。(描述不是很准确,勿喷)

二、比较一下 Image 、zImage 、 Legacy uImage 和 FIT uImage 的区别

  1. 内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。
  2. Legacy uImage是 uboot 专用的映像文件。它是在zImage之前加上一个长度为 64 字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息。从 0x40 (也就是第64位) 之后与zImage是一样的。

  3. FIT uImage 是在 Legacy uImage的基础上,为了满足Linux Flattened Device Tree(FDT)的标准,而重新改进和定义出来的一种映像文件格式。(下面再讲 FDT)

三、为什么会出现 Legacy uImage ,然后又出现 FIT uImage ?

        1. 最开始出现的是 Image,就一个普通的内核镜像。

        2. 然后为了节省空间,有了 zImage,进行了压缩可以节省空间。

        3. 至此,uboot 启动 一个Image或者 zImage,还必须要给它传递一些参数。

                 ●  镜像文件的类型,如kernel image、dtb文件、ramdisk image等等?

                 ●  镜像文件需要放在memory的哪个位置(加载地址)?

                 ●  镜像文件需要从memory哪个位置开始执行(执行地址)?

                 ●  镜像文件是否有压缩?

                 ●  镜像文件是否有一些完整性校验的信息(如CRC)?

        4. 这种方式的不足就在于,镜像本身没有带有这些参数的,用工具制作完镜像后,还需要另

            外再向uboot提供这些参数,才能正常启动(就是比较麻烦)。

        5. 如果可以把这些参数,在制作镜像的时候就一起弄到镜像里面,然后uboot 一读取镜像,就

            马上可以知道这些参数了。不需要在制作好镜像之后再另外告诉 uboot这些参数。这种带有

            以上参数的镜像格式就是 Legacy uImage。

        6. 最后一个 FIT uImage ,跟Linux Flattened Device Tree(FDT)有点关系。我直接贴一下

            其它文章吧。(大概意思就是说,当时arm linux的内核代码写得不太好,需要把一些和arm

            硬件相关的内容,挪到Device Tree那里,硬件的细节可以直接透过它传递给Linux,而不

            再需要在kernel中进行大量的冗余编码。)

Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”,引发ARM Linux社区的地震,随后ARM社区进行了一系列的重大修正。在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。读者有兴趣可以统计下常见的s3c2410、s3c6410等板级目录,代码量在数万行。
社区必须改变这种局面,于是PowerPC等其他体系架构下已经使用的Flattened Device Tree(FDT)进入ARM社区的视野。Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。
Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子结点。所谓属性,其实就是成对出现的name和value。在Device Tree中,可描述的信息包括(原先这些信息大多被hard code到kernel中):
CPU的数量和类别
内存基地址和大小
总线和桥
外设连接
中断控制器和中断使用情况
GPIO控制器和GPIO使用情况
Clock控制器和Clock使用情况
它基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备

        7. 就是因为上面那个因素,所以要把Legacy uImage 改进一下,变成 fit img (Flattened

            uImage Tree)。

四、Legacy uImage 是怎么把信息弄进镜像里的

        直接上段代码吧。

mkimage -A arm -O linux -C none -T kernel -a 0x20008000 -e 0x20008040 -n Linux_Image -d zImage uImage

各个参数意义如下
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)
  1. 从上面命令可以基本看到,参数是通过制作镜像的工具 mkimage 传入Legacy uImage的。

  2. mkimage 的可选参数基本描述了,有哪些信息是需要和可以写入到 Legacy uImage的。

五、fit img (Flattened uImage Tree) 的原理和生成

        1. 上面说了,fit img的出现,是为了跟上Linux Flattened Device Tree(FDT)的步伐而进行

            的一种改进。

        2. its文件( image source file)。

           有点类似于平时我们用的ubuntu 和centos上面的 grub.cfg配置文件,主要是配置一些启动

           参数的。(在制作Legacy uImage的时候,我们是直接传参数给mkimage,现在是把参数先

            写入 its文件而已)

        3. image data file(也就是不包含启动参数的内核镜像了)

        4. itb文件。

            这个就是最后生成的镜像文件了,是通过打包工具,把mkimage 把 its文件和linux kernel

            镜像打包而成的。也就是uboot可以直接对其进行识别和解析的FIT uImage。

        5. 贴一个 its的例子吧。

{
    description = "U-Boot uImage source file for X project";
    #address-cells = <1>;

    images {
        kernel@tiny210 {
            description = "Unify(TODO) Linux kernel for project-x";
            data = /incbin/("/home/hlos/code/xys/temp/project-x/build/out/linux/arch/arm/boot/zImage");
            type = "kernel";
            arch = "arm";
            os = "linux";
            compression = "none";
            load = <0x20008000>;
            entry = <0x20008000>;
        };
        fdt@tiny210 {
            description = "Flattened Device Tree blob for project-x";
            data = /incbin/("/home/hlos/code/xys/temp/project-x/build/out/linux/arch/arm/boot/dts/s5pv210-tiny210.dtb");
            type = "flat_dt";
            arch = "arm";
            compression = "none";
        };
        ramdisk@tiny210 {
            description = "Ramdisk for project-x";
            data = /incbin/("/home/hlos/code/xys/temp/project-x/build/out/rootfs/initramfs.gz");
            type = "ramdisk";
            arch = "arm";
            os = "linux";
            compression = "gzip";
        };
    };

    configurations {
        default = "conf@tiny210";
        conf@tiny210 {
            description = "Boot Linux kernel with FDT blob";
            kernel = "kernel@tiny210";
            fdt = "fdt@tiny210";
            ramdisk = "ramdisk@tiny210";
        };
    };
};

        6. 最后讲一下怎么用mkimage生成 itb镜像

            需要注意的是,kernel 镜像的路径和其它信息是写在 its文件里的,不需要像Legacy

            uImage那样子,给 mkimage 加很多参数了。

mkimage -f kernel_fdt.its kernel_fdt.itb
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值