时时勤拂拭,勿使惹尘埃

TOC

Categories

IoT(六)uboot镜像解析


0x1 uboot镜像格式

通常Linux krenel经过编译后会生成名称为vmlinux或vmlinuz的ELF格式文件,嵌入式系统在部署时烧录的文件格式需要用objcopy工具去制作成烧录镜像格式文件Image。但由于Image太大,因此linux kernel项目对Image进行了压缩,并且在image压缩后的文件的前端附加了一部分解压缩代码,构成压缩镜像格式zImage。
uboot自身为了支持linux kernel的启动,构建了uImage镜像格式,uImage有两种类型,Legacy-uImage和FIT-uImage:
Legacy-uImage是在zImage压缩镜像的基础上增加了64字节的头信息,使用uboot自带的mkimage工具生成了uboot自身的压缩镜像格式uImage。
FIT-uImage(flattened image tree)类似于FDT(flattened device tree)的一种实现机制。其通过一定语法和格式将一些需要使用到的镜像(例如kernel、dtb以及文件系统)组合到一起生成一个image文件。

0x2 Legacy-uImage解析

Legacy-uImage镜像格式解析比较简单,去掉64字节即0x40的头信息,即可得到zImage压缩镜像,是vmlinux经过objcopy gzip压缩后的文件,可以被qemu、boot等直接加载。
另外,uboot自带的mkimage工具,可以识别所有uboot镜像格式信息。

0x3 FIT-uImage解析

以某FIT-uImage格式的boot.img镜像为例,在头部可以看见U-Boot fitImage for Yocto GENIVI Baseline (Poky/meta-ivi)/4.4/ailabs_m1的明文信息:
FIT uImageu-boot推出了全新的image格式,其中FIT是flattened image tree的简称;而Yocto GENIVI Baseline (Poky/meta-ivi)则是一种嵌入式专用的linux发行版。
kernel镜像作为FIT的configure中的一个节点,其信息则是以节点中的属性来进行描述的。 uboot的工作就是要从FIT中提取相应的kernel节点,在节点中获取相应的属性,从而得到kernel的信息。
以下指令可以安装uboot的mkimage工具,并使用mkimage获取boot.img信息,可以看到Linux kernel偏移在0x40080000,共4254829 Bytes=0x40EC6D,使用lz4 compressed压缩但。这个偏移只是运行后的加载偏移,不是kernel在boot.img的偏移:

$ brew install u-boot-tools
//$ apt install u-boot-tools

$ mkimage -l boot.img

FIT description: U-Boot fitImage for Yocto GENIVI Baseline (Poky/meta-ivi)/4.4/ailabs_m1

Created:         Tue Apr 17 19:17:30 2018

 Image 0 (kernel@1)

  Description:  Linux kernel

  Created:      Tue Apr 17 19:17:30 2018

  Type:         Kernel Image

  Compression:  lz4 compressed

  Data Size:    4254829 Bytes = 4155.11 KiB = 4.06 MiB

  Architecture: AArch64

  OS:           Linux

  Load Address: 0x40080000

  Entry Point:  0x40080000

...
编译kernel时是通过dtc(device-tree-compiler)编译工具将.dts编译为.dtb,并将其与kernel合并打包出boot.img。所以要从dtb格式的boot.img提取kernel等文件,需要通过dtc工具进行分别提取,方式如下:
$ apt install device-tree-compiler

$ dtc -o boot.conf boot.img
得到以下文件boot.conf:
通过以上kernel与DTB中的data提取出hex数据存入文件(如使用010editor,View -> Edit As -> HexEdit -> Paste From -> Paste from Hex Test),即分别得到kernel与dtb文件。通过file指令查看kernel文件,显示为lz4压缩数据,与上文获取的信息一致;lz4 -d kernel kernel_out指令可以解开lz4压缩:
$ file kernel
kernel: LZ4 compressed data (v0.1-v0.9)
$ lz4 -d kernel kernel_out

0 评论:

发表评论