uimage头部信息详解
一、uboot中的源码展示
随便找一个主线uboot,在uboot根目录下的include/image.h文件,定义了uboot头部信息的结构体。
/*
* Legacy format image header,
* all data in network byte order (aka natural aka bigendian).
*/
typedef struct image_header {
__be32 ih_magic; /* Image Header Magic Number 0x27051956 */
__be32 ih_hcrc; /* Image Header CRC Checksum */
__be32 ih_time; /* Image Creation Timestamp */
__be32 ih_size; /* Image Data Size */
__be32 ih_load; /* Data Load Address */
__be32 ih_ep; /* Entry Point Address */
__be32 ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
ih_magic
:魔术字,固定为0x27051956
,占4字节,方便uboot判断要启动的镜像是否为uimage格式。ih_hcrc
:整个头部的crc32校验,32位校验,所以占4字节。ih_time
:时间戳,占4字节,为16进制,表示uimage生成的时间。ih_size
:镜像数据大小,即除去头部信息外的数据大小,占4字节。ih_load
:镜像数据的解压地址,uboot启动过程中,需要将镜像数据解压到DDR的地址位置。占4字节。ih_ep
:镜像解压后,启动镜像的地址位置,占4字节。ih_dcrc
:除去头部信息外,所有镜像数据的crc32校验数值,占4字节。ih_os
:表示镜像是什么操作系统下的镜像。 占1字节。ih_arch
:表示镜像所属的cpu架构,如arm、mips等。ih_type
:镜像类型,占1字节。ih_comp
:镜像的压缩类型,如gzip、lzma等,占1字节。ih_name[IHNMLEN]
: 镜像的名称。占32字节。 即名称最长32个字符。
整个头部信息,占用64字节,即0x40长度。
二、实例分析
以AP136固件的uboot header为例分析
AP136的kernel分区在后,所以镜像位置是从0x00630000
开始,头部信息占用0x40长度
,所以到0x00630040
结束。
1、ih_magic(魔术字)
首先可以看到27 05 19 56
,即0x27051956,为uboot头部信息的魔术字,可以看到该镜像是个uimage格式的镜像。这里可以看到该镜像的存储方式是大端模式,即低地址,存放高位数据
。
2、ih_hcrc(头部crc32校验)
接下来四字节DB 85 93 13
,表示头部的crc32校验,使用win32将头部信息截取出来
同时将校验位设置为0
,因为没有计算校验之前,是0。
使用linux的crc32工具,算出其校验值。
crc32 uboot_header.bin
db859313
可以看到计算出来的结果与uboot head中的DB 85 93 13
一致。 这里要注意,计算crc32之前一定要将校验位设置为0.
3、ih_time(时间戳)
再往后读取4字节,60 3C E8 2A
,即为时间戳。即0x603CE82A
,转换为10进制为1614604330
使用时间戳转换工具,可以看到镜像生成的时间是2021-03-01 21:12:10。
4、ih_size(镜像大小)
再读取4字节,00 14 4F E8
,0x00144FE8,转换为10进制为1331176
字节。将除去uboot head以外的数据截取出来。
可以到大小为1131176字节。
5、ih_load(解压地址)
往后读取4字节, 80 06 00 00
,即0x8060 0000
这个地址,uboot需要将镜像解压到该地址。
6、ih_ep (启动地址)
往后读取4字节,80 06 00 00
,即0x8060 0000
,可以看到启动镜像的地址,即解压地址。
7、ih_dcrc(镜像crc32校验)
往后读取4字节,为镜像数据的crc32校验,6B BD 55 AF
, 同样我们将提取出来的kernel进行crc32计算
crc32 kernel.bin
6bbd55af
没问题,与头部信息一致。
8、ih_os (镜像操作系统类型)
读取1字节,05
, os类型, 5对应位linux, 在uboot根目录下的include/image.h
可以看到。
/*
* Operating System Codes
*/
#define IH_OS_INVALID 0 /* Invalid OS */
#define IH_OS_OPENBSD 1 /* OpenBSD */
#define IH_OS_NETBSD 2 /* NetBSD */
#define IH_OS_FREEBSD 3 /* FreeBSD */
#define IH_OS_4_4BSD 4 /* 4.4BSD */
#define IH_OS_LINUX 5 /* Linux */
#define IH_OS_SVR4 6 /* SVR4 */
#define IH_OS_ESIX 7 /* Esix */
#define IH_OS_SOLARIS 8 /* Solaris */
#define IH_OS_IRIX 9 /* Irix */
#define IH_OS_SCO 10 /* SCO */
#define IH_OS_DELL 11 /* Dell */
#define IH_OS_NCR 12 /* NCR */
#define IH_OS_LYNXOS 13 /* LynxOS */
#define IH_OS_VXWORKS 14 /* VxWorks */
#define IH_OS_PSOS 15 /* pSOS */
#define IH_OS_QNX 16 /* QNX */
#define IH_OS_U_BOOT 17 /* Firmware */
#define IH_OS_RTEMS 18 /* RTEMS */
#define IH_OS_ARTOS 19 /* ARTOS */
#define IH_OS_UNITY 20 /* Unity OS */
#define IH_OS_INTEGRITY 21 /* INTEGRITY */
#define IH_OS_OSE 22 /* OSE */
#define IH_OS_PLAN9 23 /* Plan 9 */
#define IH_OS_OPENRTOS 24 /* OpenRTOS */
9、ih_arch(架构类型)
再读取1字节, 05
, 架构类型,对应mips架构,在uboot根目录下的include/image.h
可以看到。
/*
* CPU Architecture Codes (supported by Linux)
*/
#define IH_ARCH_INVALID 0 /* Invalid CPU */
#define IH_ARCH_ALPHA 1 /* Alpha */
#define IH_ARCH_ARM 2 /* ARM */
#define IH_ARCH_I386 3 /* Intel x86 */
#define IH_ARCH_IA64 4 /* IA64 */
#define IH_ARCH_MIPS 5 /* MIPS */
#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
#define IH_ARCH_PPC 7 /* PowerPC */
#define IH_ARCH_S390 8 /* IBM S390 */
#define IH_ARCH_SH 9 /* SuperH */
#define IH_ARCH_SPARC 10 /* Sparc */
#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
#define IH_ARCH_M68K 12 /* M68K */
#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
#define IH_ARCH_NIOS2 15 /* Nios-II */
#define IH_ARCH_BLACKFIN 16 /* Blackfin */
#define IH_ARCH_AVR32 17 /* AVR32 */
#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */
#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */
#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */
#define IH_ARCH_ARM64 22 /* ARM64 */
#define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */
#define IH_ARCH_X86_64 24 /* AMD x86_64, Intel and Via */
10、ih_type(镜像类型)
再读取1字节, 02
,表示镜像类型,对应为os kernel image
,操作系统镜像。同样在uboot根目录下的include/image.h
可以看到。
#define IH_TYPE_INVALID 0 /* Invalid Image */
#define IH_TYPE_STANDALONE 1 /* Standalone Program */
#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
#define IH_TYPE_MULTI 4 /* Multi-File Image */
#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */
#define IH_TYPE_IMXIMAGE 10 /* Freescale IMXBoot Image */
#define IH_TYPE_UBLIMAGE 11 /* Davinci UBL Image */
#define IH_TYPE_OMAPIMAGE 12 /* TI OMAP Config Header Image */
#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */
#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */
#define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */
#define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */
#define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */
#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */
#define IH_TYPE_LOADABLE 22 /* A list of typeless images */
#define IH_TYPE_RKIMAGE 23 /* Rockchip Boot Image */
#define IH_TYPE_RKSD 24 /* Rockchip SD card */
#define IH_TYPE_RKSPI 25 /* Rockchip SPI image */
#define IH_TYPE_ZYNQIMAGE 26 /* Xilinx Zynq Boot Image */
#define IH_TYPE_COUNT 27 /* Number of image types */
11、ih_comp(镜像压缩类型)
再读取1字节, 03
, 镜像的压缩算法类型,对应lzma压缩类型。同样在uboot根目录下的include/image.h
可以看到。
/*
* Compression Types
*/
#define IH_COMP_NONE 0 /* No Compression Used */
#define IH_COMP_GZIP 1 /* gzip Compression Used */
#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
#define IH_COMP_LZMA 3 /* lzma Compression Used */
#define IH_COMP_LZO 4 /* lzo Compression Used */
#define IH_COMP_LZ4 5 /* lz4 Compression Used */
12、ih_name(镜像名称)
读取剩余的32字节。名称为MIPS OpenWrt Linux-4.4.194
。
三、总结
- uboot头部占64字节。 为了方便uboot启动镜像,即
bootm
命令。 - 头部信息包括,魔术字(4)、头部crc32校验(4)、生成uimage的时间戳(4)、镜像数据大小(4)、解压地址(4)、启动地址(4)、镜像数据crc32校验(4)、镜像操作系统类型(1)、镜像架构类型(1)、镜像类型(1)、镜像压缩算法类型(1)、镜像名称(32).
- 计算头部crc32时,需要将校验位设置为0.