文档编号 // 538B24
在线
OpenixCLI Firmware 模块深度解析:IMAGEWTY 固件格式解析
概述
固件解析是嵌入式刷写工具的核心功能。全志(Allwinner)芯片使用一种名为 IMAGEWTY 的专有固件格式,将多个组件(FES、U-Boot、MBR、DTB、分区数据等)打包成单一文件。OpenixCLI 的 Firmware 模块负责解析这种二进制格式,提取各组件数据供刷写流程使用。
模块结构
|
核心导出
|
IMAGEWTY 文件格式
文件结构概览
IMAGEWTY 固件文件采用分段式结构:
|
固件组件一览
| 组件名称 | Main Type | Sub Type | 功能说明 |
|---|---|---|---|
| FES | FES | FES_1-0000000000 | Flash Eraser Script,初始化 DRAM |
| U-Boot | 12345678 | UBOOT_0000000000 | U-Boot bootloader |
| MBR | 12345678 | 1234567890___MBR | Master Boot Record 分区表 |
| GPT | 12345678 | 1234567890___GPT | GUID Partition Table |
| DTB | COMMON | DTB_CONFIG000000 | Device Tree Blob |
| sys_config | COMMON | SYS_CONFIG100000 | 系统配置文本 |
| sys_config_bin | COMMON | SYS_CONFIG_BIN00 | 系统配置二进制 |
| sys_partition | COMMON | SYS_CONFIG000000 | 分区配置 |
| board_config | COMMON | BOARD_CONFIG_BIN | 板级配置 |
| boot0_card | 12345678 | 1234567890BOOT_0 | SD 卡 Boot0 |
| bootpkg | BOOTPKG | BOOTPKG-00000000 | 启动包 |
核心数据结构
常量定义
|
ImageHeader 结构
主头结构包含固件的元信息:
|
关键特性:
#[repr(C, packed)]- 禁止内存对齐,直接映射到二进制布局- 联合体
ImageHeaderVersionData- 支持不同版本的头部结构
ImageHeaderVersionData 联合体
|
FileHeader 结构
每个文件的头结构:
|
注意: V1 和 V3 结构中 filename 字段的位置不同,这是解析时需要根据版本号处理的关键点。
ImageInfo 和 FileInfo
解析后的高层抽象结构:
|
StorageType 枚举
|
OpenixPacker 解析器
结构定义
|
加载流程
sequenceDiagram
participant User as 用户代码
participant Packer as OpenixPacker
participant File as std::fs::File
participant Header as ImageHeader/FileHeader
User->>Packer: load(path)
Packer->>File: open(path)
File-->>Packer: File handle
Packer->>File: read_exact(8 bytes)
File-->>Packer: Magic buffer
Packer->>Packer: 验证 Magic = "IMAGEWTY"
alt Magic != IMAGEWTY
Packer-->>User: PackerError::EncryptedNotSupported
else Magic == IMAGEWTY
Packer->>File: seek(Start(0))
Packer->>File: read_exact(1024 bytes)
File-->>Packer: Header buffer
Packer->>Header: ImageHeader::parse()
Header-->>Packer: ImageHeader
loop i = 0..num_files
Packer->>File: seek(1024 + i * 1024)
Packer->>File: read_exact(1024 bytes)
File-->>Packer: FileHeader buffer
Packer->>Header: FileHeader::parse()
Header-->>Packer: FileHeader
end
Packer->>Packer: 设置 image_loaded = true
Packer-->>User: Ok(())
end
load 方法实现
|
文件提取方法
|
预定义组件快捷方法
|
预定义组件查找表
ImageDataEntry 结构
|
IMAGE_DATA_TABLE 常量
|
HashMap 快速查找
|
Android Sparse 格式支持
Sparse Header 结构
|
Chunk Header 结构
|
Sparse 格式检测
|
代码亮点
1. #[repr(C, packed)] 二进制映射
|
作用:
#[repr(C)]- 使用 C 语言布局规则#[repr(packed)]- 禁止对齐,字段紧密排列
嵌入式开发中的应用: 直接将结构体映射到二进制数据,避免手动偏移计算。
2. Union 处理版本差异
|
安全访问:
|
3. 原始指针解析
|
原理: 将字节数组的指针转换为结构体指针,直接引用内存。
4. once_cell::Lazy 延迟初始化
|
优势:
- 首次访问时初始化,避免启动开销
- 线程安全
- 替代
lazy_static!宏
5. 分区名称到 SubType 的转换
|
调用流程分析
固件加载流程
|
组件提取流程
|
分区数据提取流程
|
实践示例
解析固件文件
|
输出示例
|
数据结构关系图
classDiagram
class OpenixPacker {
+file: Option~File~
+image_header: Option~ImageHeader~
+file_headers: Vec~FileHeader~
+is_encrypted: bool
+image_loaded: bool
+load(path)
+get_image_info() ImageInfo
+get_fes() Vec~u8~
+get_uboot() Vec~u8~
+get_mbr() Vec~u8~
+get_file_data_by_filename() Vec~u8~
+get_file_data_by_maintype_subtype() Vec~u8~
}
class ImageHeader {
+magic: [u8; 8]
+header_version: u32
+header_size: u32
+ram_base: u32
+version: u32
+image_size: u32
+data: ImageHeaderVersionData
+num_files() u32
+parse(data)
}
class ImageHeaderVersionData {
+v1: ImageHeaderV1
+v3: ImageHeaderV3
}
class FileHeader {
+filename_len: u32
+total_header_size: u32
+maintype: [u8; 8]
+subtype: [u8; 16]
+data: FileHeaderVersionData
+stored_length() u32
+original_length() u32
+offset() u32
+filename_str() String
}
class ImageInfo {
+header: ImageHeader
+files: Vec~FileInfo~
+is_encrypted: bool
+image_size: u32
+num_files: u32
}
class FileInfo {
+filename: String
+maintype: String
+subtype: String
+stored_length: u32
+original_length: u32
+offset: u32
}
OpenixPacker --> ImageHeader
OpenixPacker --> FileHeader
OpenixPacker --> ImageInfo
ImageHeader --> ImageHeaderVersionData
FileHeader --> FileHeaderVersionData
ImageInfo --> FileInfo
ImageInfo --> ImageHeader
微信
支付宝
导航 // 相关文章