news 2026/10/16 2:52:56

coreboot 中 MediaTek 固件镜像处理工具全解析:gen-bl-img.py 与 check-pi-img.py 实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
coreboot 中 MediaTek 固件镜像处理工具全解析:gen-bl-img.py 与 check-pi-img.py 实战指南
  • 固件
  • 嵌入式
  • 操作系统
  • 驱动开发

【免费下载链接】coreboot

Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We don't handle Pull Requests.

项目地址:https://gitcode.com/gh_mirrors/co/coreboot
点击查看免费下载

导读

coreboot 在构建 MediaTek(MT8173/MT8183/MT8189/MT8196 等)平台的启动镜像时,需要把标准 coreboot 产物转换成 MediaTek 芯片专用的启动格式,并验证第三方 PI_IMG 固件的合法性。本文以仓库中的 util/mediatek/description.md 为线索,结合 gen-bl-img.py 与 check-pi-img.py 的完整源码,逐字段讲解 MediaTek bootloader 头的生成算法、PI_IMG 的 cookie 校验规则、构建系统集成方式及运行时消费链路,读完即可独立理解并正确使用这两个工具。

一、工具定位:MediaTek 平台固件构建链路的两个关键环节

MediaTek 的 ARM64 平台(如 MT8173、MT8183)采用与主流 x86 平台不同的启动镜像格式:芯片 BootROM 期望在存储介质(eMMC 或 SPI NOR)的起始位置读到带特定魔数(Magic)的 bootloader 头,随后按布局加载 coreboot 的 bootblock 代码。因此构建流程中需要:

  • gen-bl-img.py:把 coreboot 编译出的bootblock.raw.bin打包成带 MediaTek 专用头(GFH 信息块 + SHA-256 校验 + 设备引导头)的bootblock.bin;
  • check-pi-img.py:校验厂商提供的PI_IMG固件(pi_img.img)内部 cookie 个数是否符合预期,防止把损坏或错误的固件烧进 CBFS。

两个脚本均为 Python 3 单文件实现,无第三方依赖,位于仓库 util/mediatek/ 目录下。

二、gen-bl-img.py:生成 MediaTek bootloader 头

2.1 命令行用法

./util/mediatek/gen-bl-img.py <chip> <flash_type> <input_file> <output_file>

参数说明(与脚本内main()的提示一致):

参数取值含义
chipmt8173/mt8183/mt8189/mt8196SoC 型号,决定 GFH 加载地址
flash_typeemmc/sf启动介质类型,决定设备头魔数(EMMC_BOOT或SF_BOOT)
input_file任意路径待封装的原始镜像(通常是bootblock.raw.bin)
output_file任意路径生成的带头的最终镜像

脚本内部仅对输入文件做读取与打包,不修改输入文件。注意脚本中main()打印的用法提示仅列出mt8173|mt8183,但gen_gfh_info()的条目表实际已支持四个芯片(见下节),这是脚本提示文本相对滞后于能力的一点,使用时以芯片条目表为准。

2.2 处理流水线

gen_preloader(chip_ver, flash_type, data)是整个工具的核心,其流程可概括为四步:

  1. 调用gen_gfh_info()生成 176 字节的 GFH(Generic File Header)信息块;
  2. 计算sha256(gfh_info + data),得到 32 字节镜像哈希,追加在数据之后;
  3. 将gfh_info + data + hash整体以0xff填充对齐到 512 字节边界(align(..., 512, b'\xff'));
  4. 调用gen_emmc_header()/gen_sf_header()生成设备引导头,最终输出header + data。

其结构关系可概括为:

| 设备引导头 (512B ×3, 含 EMMC_BOOT/SF_BOOT + BRLYT 布局) | | GFH 信息块 (176B) | 原始数据 (bootblock.raw.bin) | SHA-256 (32B) | 0xff 填充对齐 |

2.3 GFH 信息块字段解析

gen_gfh_info()用'<44I'(44 个小端 uint32,共 176 字节)打包一段固定结构:

  • 前 4 个字包含魔数0x014d4d4d(小端下对应 ASCII 片段MMM+0x01)、块大小0x00000038(56,对应首子块长度)、0x454c4946与0x464e495f(小端下对应 ASCII 串FILE与_INF,指示这是一个文件信息子块)、文件名长度0x0000004f、版本0x00000001、类型0x01050001;
  • 第 10 个字load_addr由芯片条目表决定:entries[chip] - gfh_size,其中gfh_size = 176。各芯片的基准地址为:
芯片基准地址entries[chip]实际 load_addr
mt81730x000C10000x000C0F50
mt81830x002010000x00200F50
mt81890x020010000x02000F50
mt81960x020010000x02000F50
  • 第 11 个字load_size = gfh_size + len(data) + 32(GFH + 数据 + SHA-256 摘要长度),随后紧跟0x00020000、0x000000a8、0x00000020、0x000000B0等区块长度与偏移描述;
  • 尾部的0x52000000、0x00006400、0x00001388等字段与 GFH 中各类子块的类型标识及属性相关,其余大量零字为保留字段。由于该结构属于 MediaTek 未公开的启动协议细节,脚本以固定常量形式写死,用户无需也无法改动。

2.4 设备引导头:EMMC_BOOT 与 SF_BOOT

gen_emmc_header()与gen_sf_header()结构完全对称,共 3 × 512 字节:

  • 第 1 个 512 字节块:struct.pack('<12sII', b'EMMC_BOOT', 1, 512)(或b'SF_BOOT'),即 12 字节魔数 + 版本号1+ 首块大小512,剩余部分以0xff填充到 512 字节;
  • 第 2 个 512 字节块:BRLYT(Boot Rom Layout)布局描述,struct.pack('<8sIIIIIIII', ...)包含:
    • 魔数BRLYT;
    • 版本1;
    • 偏移2048与大小2048 + len(data):指向下一段的起始位置与总大小;
    • 未知标识0x42424242(ASCIIBBBB);
    • 类型字段:eMMC 为0x00010005,SPI 为0x00010007——这是两个介质头的唯一实质差异;
    • 再次记录偏移与大小,以及条目数量1;
    • 固定补 140 字节0x00,再以0xff填充至 512 字节;
  • 第 3 个 512 字节块:全部为0x00(b'\0' * 1024补足)。

gen_dev_header字典把'emmc'/'sf'映射到上述两个函数,gen_preloader()据此选择头类型,因此传错flash_type会在头内留下错误的魔数与介质类型标识。

2.5 对齐与填充细节

  • 数据区对齐用0xff(Flash 编程常以0xff为擦除态),代码:align(data, size, pattern=b'\xff');
  • 对齐公式为(len(data) + (size - 1)) & ~(size - 1),即向上取整到 512 的整数倍;
  • padding()在不足时用指定 pattern 补足,若数据恰好等长则原样返回(不做截断)。

三、check-pi-img.py:校验 PI_IMG 固件的 cookie 标记

3.1 命令行用法

./util/mediatek/check-pi-img.py <pi_img>

3.2 校验逻辑

脚本逻辑非常简洁:从偏移0x200(HEADER_OFFSET)开始,以 4 字节为单位逐段读取整个文件,统计数值等于0x17C3A6B4(COOKIE)的次数;只有恰好检测到2 个cookie 才判定合法,否则抛出ValueError:

raise ValueError("Invalid PI_IMG {} (expected 2 cookies; found {})" .format(pi_img, cookie_count))

该 cookie 是 MediaTek PI 镜像内部的标志魔数,用于在整包固件中定位关键描述符。文件被截断、字节序错误或混入其他固件都会导致计数不等于 2,从而被工具拒绝。脚本返回非零退出码,便于构建系统把校验失败当作构建失败处理。

3.3 在构建系统中的强制校验

在 src/soc/mediatek/mt8196/Makefile.mk 中,校验被做成独立的 phony 目标,并作为coreboot.pre的 order-only 前置依赖,确保每次构建正式产物前必然执行:

PI_IMG := $(MT8196_BLOB_DIR)/$(call strip_quotes,$(CONFIG_PI_IMG_FIRMWARE)) .PHONY: check_pi_img check_pi_img: $(PI_IMG) ./util/mediatek/check-pi-img.py $< # Make sure check_pi_img is always run. $(obj)/coreboot.pre: | check_pi_img

其中$(CONFIG_PI_IMG_FIRMWARE)默认值为pi_img.img,位于3rdparty/blobs/soc/mediatek/mt8196/目录下。

四、构建系统集成:各 SoC 的调用方式

gen-bl-img.py 被各 MediaTek SoC 的 Makefile 以定制规则接入:bootblock 的最终产物由bootblock.raw.bin通过该脚本转换得到。

SoCMakefile 规则chipflash_type
MT8173src/soc/mediatek/mt8173/Makefile.mkmt8173sf
MT8183src/soc/mediatek/mt8183/Makefile.mkmt8183emmc
MT8189src/soc/mediatek/mt8189/Makefile.mkmt8189sf
MT8196src/soc/mediatek/mt8196/Makefile.mkmt8196sf

示例规则(MT8189/MT8196 相同):

$(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin ./util/mediatek/gen-bl-img.py mt8189 sf $< $@

可见 MT8183 平台从 eMMC 启动(emmc头),而 MT8173、MT8189、MT8196 从 SPI NOR 启动(sf头)。日常构建无需手动调用该脚本,make会自动完成转换。

五、运行时消费链路:PI_IMG 进入 FSP 与 MCUPM

理解 check-pi-img.py 校验的对象,需要看 PI_IMG 在运行时的用途:

  1. 固件打包进 CBFS:在 MT8189/MT8196 的 Makefile 中,pi_img.img与 DPM、MCUPM、SPM、SSPM 等固件一起以raw类型、LZ4压缩方式写入 CBFS(见 src/soc/mediatek/mt8189/Makefile.mk 的firmware-files列表);
  2. 加载与传递:src/soc/mediatek/common/pi_image.c 中的pi_image_load()通过mtk_init_mcu()从 CBFS 加载固件到dram_dma缓冲区,再由pi_image_add_mtk_fsp_params()以FSP_PARAM_TYPE_PI_IMG与FSP_PARAM_TYPE_PI_IMG_CSRAM两个参数注册进 MediaTek FSP 接口;
  3. Kconfig 说明:在 src/soc/mediatek/mt8189/Kconfig 中,PI_IMG_FIRMWARE的 help 明确写到:PI image 的主要用途是将各种频率与电压缩放参数和设置传递给 MCUPM;
  4. 错误状态定义:src/soc/mediatek/common/include/soc/mtk_fsp_common.h 定义了FSP_STATUS_INVALID_PI_IMG状态码,说明 FSP 侧同样会对 PI_IMG 的合法性做校验——check-pi-img.py 正是构建阶段的第一道防线。

通用固件加载逻辑在 src/soc/mediatek/common/mcu.c 的mtk_init_mcu()中:cbfs_load()从 CBFS 取固件,随后(若配置了run_address)拷贝到运行地址并做内存屏障,最后复位对应 MCU。因此check_pi_img构建目标实际守护的是这条"CBFS → FSP → MCUPM 频率电压缩放"链路的输入质量。

六、常见使用场景与命令速查

手动校验厂商提供的 PI 镜像:

python3 util/mediatek/check-pi-img.py 3rdparty/blobs/soc/mediatek/mt8196/pi_img.img # 校验通过则无输出;失败则报: # ValueError: Invalid PI_IMG ... (expected 2 cookies; found N)

手动为 bootblock 打头(对应 MT8196 的 SPI 启动配置):

python3 util/mediatek/gen-bl-img.py mt8196 sf build/bootblock.raw.bin build/bootblock.bin

结语

这两个看似只有一行的工具说明背后,是 MediaTek SoC 与 coreboot 构建系统深度绑定的产物:gen-bl-img.py负责把通用 coreboot 产物翻译成 BootROM 能识别的EMMC_BOOT/SF_BOOT+BRLYT+ GFH 格式,check-pi-img.py则通过双 cookie 规则在构建早期拦截异常的 PI_IMG 固件。理解它们的输入输出与集成方式,是排查 MediaTek 平台启动失败、或为新增 MediaTek SoC 接入 coreboot 构建链路的必要基础。

  • 固件
  • 嵌入式
  • 操作系统
  • 驱动开发

【免费下载链接】coreboot

Read-only mirror of https://review.coreboot.org/coreboot.git. Synced every hour. We don't handle Pull Requests.

项目地址:https://gitcode.com/gh_mirrors/co/coreboot
点击查看免费下载
上一篇:从源码构建与校验安装 Apache Airflow Airbyte Provider:发布包下载、PGP/SHA512 完整性验证与源码构建全指南
下一篇:Linux-Tutorial:GoAccess 安装与配置实战——基于 Nginx 访问日志的实时分析与 HTML 报表生成

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 2:52:31

Lesamnta算法的各种密码分析方法全面盘点

Lesamnta算法的各种密码分析方法全面盘点Lesamnta作为SHA-3竞赛的候选算法&#xff0c;其密码分析研究主要集中在缩减轮次的攻击上&#xff0c;涵盖了差分、积分、不可能差分、中间相遇等多种经典方法。其轻量级版本Lesamnta-LW&#xff08;已纳入ISO/IEC 29192-5标准&#xff…

作者头像 李华
网站建设 2026/10/16 2:52:28

半导体 ESD 隐性静电损伤:量产产线的漏洞排查方法

一批产品在工厂内部测试全部合格&#xff0c;出货两个月后客户端陆续反馈失效。失效分析结论写着"栅氧击穿"&#xff0c;但工艺参数、来料检验、可靠性抽测都没有异常——最后查到的原因&#xff0c;是产线上某个工位的防静电手环接地线松动&#xff0c;操作员戴了两…

作者头像 李华
网站建设 2026/10/16 2:51:52

Fab刻蚀工艺:同一Recipe批次间刻蚀深度差异管控思路

刻蚀是Fab里最考验功力的工序之一。同一套Recipe&#xff0c;跑出来的晶圆之间&#xff0c;刻蚀深度有时候会出现肉眼看不出来的差异——深了0.02微米&#xff0c;浅了0.03微米&#xff0c;单片看起来似乎没什么问题&#xff0c;但当这些偏差累积到几十层薄膜堆叠的器件上的时候…

作者头像 李华
网站建设 2026/10/16 2:51:36

IEC 62619:2022储能电池认证:电芯到系统的安全测试与BMS设计要点

简介&#xff1a;IEC 62619-2022 是国际电工委员会发布的第二版工业用二次锂电池安全标准&#xff0c;面向电池制造商、系统集成商、检测认证机构及工业设备工程师&#xff0c;覆盖固定式储能、动力电源及备用电源等典型工业场景。该标准规定了碱性或其他非酸电解质体系下&…

作者头像 李华