← 返回信息流
AI 资讯Hacker News·4 小时前

将ThinkPad X61移植至Coreboot固件

原标题:Porting the ThinkPad X61 to Coreboot

速览

该资讯报道了将经典ThinkPad X61笔记本电脑移植到Coreboot固件的过程。Coreboot是一个开源固件项目,旨在替代传统的BIOS,提供更快的启动速度和更高的安全性。这一移植工作对于延长老旧硬件的使用寿命及推动开源固件发展具有积极意义。

AI 深度解读

将 ThinkPad X61 移植到 Coreboot:AI 辅助逆向工程的实战

背景

作者拥有长达十余年的 ThinkPad 收藏与使用经历,从早期的 ThinkPad x60 开始,便因接触 GNU Emacs 中的 GNU 项目介绍而对自由软件产生浓厚兴趣。随着对自由固件(libreboot)的追求,作者逐步深入 coreboot 社区,最终成为 coreboot 的贡献者,并因此加入 9elements 公司工作。

在这一过程中,作者收集了多款 ThinkPad 机型,包括 x200、x220、x201、R500 以及支持 Skylake/Kabylake 架构的 T480。然而,在作者的收藏中始终缺失一代经典机型——ThinkPad X61。

ThinkPad X61 采用 GM965 北桥和 ICH8 南桥。虽然 GM965 与已支持的 x200 上的 GM45 相似(仅支持 DDR2),ICH8 也与已支持的 ICH9 类似,但该平台的官方文档从未泄露,这意味着逆向工程是获取信息的唯一途径。过去,曾有人尝试使用 SerialICE 等工具在 QEMU 中运行固件并将 I/O 和 MMIO 转发至实际硬件,但均未成功实现 coreboot 的完整移植。

核心内容

AI 辅助逆向工程的尝试

2024年3月,作者开始探索将大语言模型(LLM)技术更深度地整合到工作流中。虽然 LLM 在快速原型设计方面表现良好,但其在复杂的逆向工程任务中的表现尚属未知。作者当时使用的是 Anthropic 的 Claude Opus 4.6(当时的业界顶尖模型)。

事实证明,LLM 是加速逆向工程过程的强大工具。传统上,完成 GM965/ICH8 平台(即 X61)的 coreboot 移植需要 3 到 6 个月的专注时间,而作者并无此空闲。作者首先在一个下载的厂商 BIOS 镜像上进行了测试,结果令人满意。随后,作者购买了实体设备并成功使其运行。

传统 BIOS 信息转储

在深入理解厂商固件逻辑之前,作者首先从正常运行的系统中转储尽可能多的信息。拥有“已知良好值”至关重要,当 DRAM 训练失败或 USB 突然失效时,这些参考数据能用于对比排查。此外,这些信息还为平台的其他部分提供了线索,如嵌入式控制器(EC)设置、ACPI 表、PCI 配置、GPIO 引脚定义以及 HDA 动词表。

使用的工具包括:

  • inteltool:提供 PCI 配置空间概览以及北桥和南桥寄存器的大部分信息。
  • lspci:用于快速检查 Linux 系统如何看待该机器。
  • acpidump / acpixtract / iasl -d:用于转储、拆分和反编译 ACPI 表,以可读形式展示厂商固件如何向操作系统描述设备、电源管理和 EC 方法。
  • ectool:用于查看 EC RAM 和行为,因为 ThinkPad 往往将大量板级特定细节隐藏在此处。
  • 其他:保存了 CPU 信息和 HDA 编解码器信息,以防在长时间凝视固件代码时遗漏。

设置 AI 代理工具与固件发现

X61 使用 Phoenix BIOS,第一步是使用 bios_extract 将镜像拆分为单独的模块。随后,作者为 AI 代理配置了可直接使用的工具:

  1. ghidra-cli:配合 SKILL.md 使用,使 AI 能够向 Ghidra 提问,而无需作者全程操作 GUI。这对于处理看起来源自 Intel MRC(内存参考代码)的 PE32 模块(如 raminit)非常有效,因为原始代码可能为 C 语言,反编译器输出具有实际参考价值。
  2. radare2:配合相应的 skill 使用。由于固件的大部分代码是 16 位实模式,radare2 在处理此类代码以及周围的胶水代码时,AI 代理往往能取得更好的成功。

意外发现:作者在镜像中发现了至少 3 个版本的 raminit。推测这是一种 A/B 布局,其中只读(RO)副本用于恢复目的,跳过了正常的 raminit 流程,旨在将机器恢复到足以重新刷写其余 BIOS 的状态。这与 Lenovo 文档中描述的闪存顶部 64K 被写保护的行为相符。

“氛围逆向工程”与现实的落差

作者起初描述了一个近乎神话般的场景:LLM 提取了所有 raminit 初始化序列,仅通过两个提示词(prompts)就完成了 coreboot 移植的编写。作者甚至一边在健身房举铁一边让 AI 运行,回来后第一次尝试即成功。

然而,作者随即澄清:“上一节完全是谎言。”

LLM 需要大量的引导(hand-holding)。作者之所以能成功,得益于其对类似平台(如 x200 和 x60)的深厚知识储备,以及对启动所需细节的熟悉。作者列出了在引导模型时必须进行干预的关键点,包括:

  • GPIO 复用:ThinkPad X61 在 GPIO42 上有 SMBUS 的 GPIO 复用,导致只能看到 SPD 或 EEPROM 之一。操作系统启动后仅可见 EEPROM,而非 SPD。
  • 内存频率解码:内存控制器支持 DDR2 533MT/s 和 666MT/s,而非 666MT/s 和 800MT/s。正确解码硬件寄存器至关重要。
  • FSB 频率读取:GMCH FSB 频率需从 MCHBAR 寄存器读取,而非某些 PCI 寄存器。
  • 寄存器大小错误:存在大量错误大小的寄存器读写操作,例如向 16 位寄存器写入 32 位值可能会破坏需要保持不变的顶部 16 位。
  • CAS 语义混淆:模型在 coreboot 的编码方式与 MRC 的方式之间的 CAS 语义上经常感到困惑。
  • 多版本 raminit 干扰:固件中的多个 raminit 版本也严重混淆了模型。

正如人类逆向工程一样,追踪和转储数值并与已知值进行比较对于发现问题至关重要。Lubomir Rintel 之前使用 SerialICE 追踪 raminit 的工作也发挥了作用。

刷写与测试工作流

移植并未在第一次尝试时就成功引导。作者的测试和刷写设置如下:

  • 调试接口:利用带有 RS232 UART 连接器的底座(与 ThinkPad x60 兼容),通过白色连接器进行调试。
  • 硬件刷写:将主板从底座取出,使用夹子连接到主板底部的闪存芯片。注意芯片为 SOIC8 封装,尽管夹子看起来像用于 SOIC16,但较大的引脚可以兼容较小的芯片。
  • 刷写命令:主板包含 Intel 描述符、GBE 和 ME 区域,作者暂时未触碰这些区域。使用以下命令进行刷写:
    flashprog -p ch341a_spi --ifd -i bios -w
    

关键要点

  • AI 是加速器而非替代者:LLM(如 Claude Opus 4.6)能显著加速逆向工程流程,特别是在解析反编译代码和生成初始框架方面,但无法完全替代人类专家的知识。
  • 领域知识不可或缺:成功移植依赖于作者对前代(x60)和后代(x200)平台硬件细节的深刻理解。AI 模型在寄存器定义、内存时序、GPIO 复用等具体硬件行为上极易出错,需要人工精准引导。
  • 混合工具链的有效性:结合 ghidra-cli(处理高级语言风格的 MRC 代码)和 radare2(处理 16 位实模式代码)为 AI 代理提供了最佳的分析环境。
  • 传统转储仍是基础:在依赖 AI 之前,通过 inteltoolacpidumpectool 等工具获取厂商 BIOS 的已知良好值(Known Good Values)是调试和验证 AI 生成代码正确性的基石。
  • **逆向工程的复杂性
查看原文 →blog.aheymans.xyz