HP Chromebox G3 自编译 Coreboot UEFI 记录
这篇是一次 HP Chromebox G3(Noibat)自编译 coreboot UEFI 固件的完整记录,重点不只是“编译成功”,而是把桌面机上不该出现的电池、充电策略、声卡兼容 ID、UEFI Payload 容量等坑都一起处理掉。
背景
HP Chromebox G3(Google 代号 Noibat)是一台基于 Intel Comet Lake-U 平台的小型台式机。MrChromebox 维护的 coreboot 分支提供了 UEFI 固件支持,但原版固件有几个桌面机不需要的问题:
- ChromeEC 会暴露
BAT0电池 ACPI 设备,导致 Windows 显示电池图标并启用笔记本电源策略 - DPTF 包含充电性能控制(Charger Performance Control),台式机无电池,这些配置无意义
- Realtek RT5682 声卡的 ACPI HID 是
10EC5682,macOS 需要兼容 IDRTL5682才能驱动 - GitHub Actions 因账号 billing 限制无法运行,ARM64 编译 crossgcc-i386 会失败,必须在 x86 主机上编译
一张图看完整流程
目标
构建一个 "桌面 /Win/macOS 友好" 的 coreboot UEFI 固件变体 noibat-mac,包含以下实验性修改:
- 隐藏 BAT0 电池设备(
_STA返回 0) - 移除 DPTF 充电性能控制
- 添加 RT5682 兼容 ID
_CID=RTL5682 - 兼容 shallow clone(
git describe --always)
环境
- 主机: x86_64 Ubuntu 24.04
- CPU: 4 核
- 磁盘: ~15GB 可用空间(编译中间产物 + crossgcc)
- 源码: MrChromebox/coreboot branch
MrChromebox-2603 - 目标 Board:
google/puffvariantnoibat-mac
编译过程
1. 依赖安装
sudo apt-get update
sudo apt-get install -y \
build-essential git curl wget ca-certificates \
gcc g++ make flex bison gnat \
libssl-dev libncurses-dev zlib1g-dev \
uuid-dev nasm iasl pkg-config python3 python3-pip \
unzip xz-utils bzip2 cpio rsync file
⚠️
iasl(ACPI 编译器)必须安装,否则构建时找不到 crossgcc 编译的 iasl 会直接报错停止。
2. 克隆 Builder 仓库
git clone https://github.com/rothdren-lion/noibat-bios-builder.git
cd noibat-bios-builder
这个仓库只是一个编排脚本,不包含 coreboot 完整源码,编译时会自动拉取。
3. 拉取 Coreboot 源码
export WORKDIR="$PWD/work"
export GIT_HTTP_VERSION=HTTP/1.1
export GIT_TERMINAL_PROMPT=0
./scripts-build-noibat.sh noibat-mac
脚本会执行 git clone --branch MrChromebox-2603 --depth 1 https://github.com/MrChromebox/coreboot.git work/coreboot。
⚠️ 国内环境直接访问 GitHub 可能 TLS 握手失败,使用
GIT_HTTP_VERSION=HTTP/1.1可绕过部分 TLS 问题。
4. 预缓存 CrossGCC 依赖(关键踩坑点)
coreboot 的 crossgcc 构建系统会从 coreboot.org 下载交叉编译工具链的源码包,但 coreboot.org 经常返回 403 Forbidden。替代方案是从 GNU 官方镜像下载,但 部分包的 hash 与 coreboot 期望的不一致(如 binutils-2.45.tar.xz),会导致 hash 校验失败。
解决方案:提前从正确来源下载所有 tarball 并放入缓存目录:
TARBALL_DIR="work/coreboot/util/crossgcc/tarballs"
mkdir -p "$TARBALL_DIR"
# 这些包从 GNU mirror 下载,hash 与 coreboot 一致
curl -Lf -o "$TARBALL_DIR/gmp-6.3.0.tar.xz" \
"https://ftpmirror.gnu.org/gmp/gmp-6.3.0.tar.xz"
curl -Lf -o "$TARBALL_DIR/mpfr-4.2.2.tar.xz" \
"https://ftpmirror.gnu.org/mpfr/mpfr-4.2.2.tar.xz"
curl -Lf -o "$TARBALL_DIR/mpc-1.3.1.tar.gz" \
"https://ftpmirror.gnu.org/mpc/mpc-1.3.1.tar.gz"
curl -Lf -o "$TARBALL_DIR/gcc-14.2.0.tar.xz" \
"https://ftpmirror.gnu.org/gcc/gcc-14.2.0/gcc-14.2.0.tar.xz"
# ⚠️ binutils 必须从 sourceware.org 下载,GNU mirror 版本 hash 不匹配!
curl -Lf -o "$TARBALL_DIR/binutils-2.45.tar.xz" \
"https://sourceware.org/pub/binutils/releases/binutils-2.45.tar.xz"
curl -Lf -o "$TARBALL_DIR/nasm-2.16.03.tar.bz2" \
"https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/nasm-2.16.03.tar.bz2"
curl -Lf -o "$TARBALL_DIR/acpica-unix-20250807.tar.gz" \
"https://downloadmirror.intel.com/864114/acpica-unix-20250807.tar.gz"
验证 hash:
cd work/coreboot/util/crossgcc
for f in tarballs/*; do
name=$(basename "$f")
if [ -f "sum/$name.cksum" ]; then
expected=$(sed -e 's@.*\([0-9a-f]\{40,\}\).*@\1@' < "sum/$name.cksum")
actual=$(sha1sum "$f" | awk '{print $1}')
if [ "$expected" = "$actual" ]; then
echo "✓ $name"
else
echo "✗ $name HASH MISMATCH"
fi
fi
done
踩坑: 如果 binutils 从 GNU mirror 下载,hash 会是
b576a0...,但 coreboot 期望的是09fd8a...。必须从sourceware.org下载才能 hash 匹配。
5. 手动应用实验性补丁
由于 shallow clone 和重复应用的问题,git apply 会失败。我们手动修改源文件:
5.1 build-uefi.sh — 兼容 shallow clone
cd work/coreboot
sed -i 's/rev=$(git describe --tags --dirty)/rev=$(git describe --tags --dirty --always)/' build-uefi.sh
shallow clone 没有 tag 信息,git describe --tags 会失败。加 --always 后回退到 commit hash。
5.2 ec.h — 定义 NOIBAT_DESKTOP_NO_BATTERY
// 文件: src/mainboard/google/puff/variants/noibat/include/variant/ec.h
// 在 #endif 之前添加:
/*
* HP Chromebox G3 / Noibat is a desktop Chromebox, not a laptop.
* The common ChromeEC ACPI block always exposes ACPI0003 AC adapter and
* PNP0C0A BAT0 battery devices. Windows then shows a battery icon and may
* select laptop-style power UX/policies even though the machine has no
* battery. Keep the EC, AC power-source state, DPTF CPU/fan/thermal policy,
* and PD notifications intact, but make the battery package effectively
* disappear from the OS.
*/
#define NOIBAT_DESKTOP_NO_BATTERY
5.3 battery.asl — 条件隐藏电池设备
修改 Device (BAT0) 中已有的 _STA 方法:
// 文件: src/ec/google/chromeec/acpi/battery.asl
// 将 BAT0 中原来的 _STA 方法:
Method (_STA, 0, Serialized)
{
Return (BSTA (0))
}
// 替换为:
Method (_STA, 0, Serialized)
{
#ifdef NOIBAT_DESKTOP_NO_BATTERY
Return (0)
#else
Return (BSTA (0))
#endif
}
踩坑: 不能用
#ifndef包裹整个Device (BAT0)块!因为ec.asl中的Notify(BAT0, ...)仍然引用 BAT0,如果 BAT0 设备不存在,ASL 编译会报Object does not exist错误。用_STA=0的方式,设备存在但 OS 看不到,完美解决。
踩坑: 不能在 BAT0 内新增第二个
_STA方法!ASL 不允许同一作用域内重复定义方法名,会报Name already exists in scope。必须修改原有的_STA。
5.4 ec.asl — 修复 ECPD 前向引用
// 文件: src/ec/google/chromeec/acpi/ec.asl
// 将直接引用 ECPD 的 Notify 调用:
Notify (\_SB.PCI0.LPCB.EC0.CREC.ECPD, 0x80)
// 替换为 CondRefOf 安全引用:
If (CondRefOf (\_SB.PCI0.LPCB.EC0.CREC.ECPD)) {
Notify (\_SB.PCI0.LPCB.EC0.CREC.ECPD, 0x80)
}
踩坑: ASL 不支持前向引用。
ECPD设备定义在_Q16/_Q1C方法之后,但 Notify 在之前就引用了它,导致Object does not exist编译错误。用CondRefOf是 coreboot 自身代码库中已有的模式。
5.5 overridetree.cb — 移除充电控制 + 添加声卡 CID
cd work/coreboot
OTREE="src/mainboard/google/puff/variants/noibat/overridetree.cb"
# 移除 Charger Performance Control 注册项(5行)
sed -i '/## Charger Performance Control/,/register "controls.charger_perf\[3\]"/d' "$OTREE"
# 在 RT5682 的 hid 行后添加 cid
sed -i 's/register "hid" = ""10EC5682""/register "hid" = ""10EC5682""\n\t\t\t\tregister "cid" = ""RTL5682""/' "$OTREE"
5.6 复制自定义 Config
cp patches/config.noibat-mac.uefi work/coreboot/configs/cml/config.noibat-mac.uefi
5.7 UefiPayloadPkg.fdf — 增大 FV 容量
FDF="work/coreboot/payloads/external/edk2/workspace/mrchromebox/UefiPayloadPkg/UefiPayloadPkg.fdf"
# RELEASE 模式下 FV 从 8MB 增大到 9MB
sed -i '/!else/,/!endif/ s/DEFINE FD_SIZE = 0x0800000/DEFINE FD_SIZE = 0x0900000/' "$FDF"
sed -i '/!else/,/!endif/ s/DEFINE NUM_BLOCKS = 0x800/DEFINE NUM_BLOCKS = 0x900/' "$FDF"
踩坑: UEFI payload 编译后约 8.6MB,超过默认的 8MB FV 限制。GenFv 报错
the required fv image size 0x83e160 exceeds the set fv image size 0x800000。增大到 9MB 解决。
6. 运行 Kconfig
cd work/coreboot
make olddefconfig KCONFIG_CONFIG="configs/cml/config.noibat-mac.uefi"
7. 编译 CrossGCC + IASL
make crossgcc-i386 iasl CPUS="$(nproc)" BUILDGCC_OPTIONS="-m"
首次编译约 15-25 分钟。crossgcc 编译 i386-elf 交叉工具链(GCC 14.2 + Ada 支持)和 IASL ACPI 编译器。
踩坑: 必须确保所有 tarball hash 正确,否则中途失败需要删除错误文件重新下载。
8. 编译 UEFI ROM
bash build-uefi.sh noibat-mac
编译过程约 3-5 分钟,包含:
- coreboot 主板代码编译
- ACPI 表生成(DSDT 用 iasl 编译)
- EDK2 UEFI Payload 编译
- FSP(Firmware Support Package)集成
- CBFS 打包
9. 输出
ls -lh out/
# coreboot.rom 16MB ← 完整的 UEFI 固件镜像
ROM 内容一览
cbfs.ioplus 0x000 raw 12200 none
config 0x817c0 raw 4846 LZMA
revision 0x82b00 raw 785 none
build_info 0x82e40 raw 117 none
fallback/dsdt.aml 0x82f00 raw 12200 none ← 我们的 ACPI 补丁
ecrw 0x85f00 raw 139116 none
fspm.bin 0xa7fc0 fsp 462848 none
fsps.bin 0x119000 fsp 190102 LZMA
vbt.bin 0x147700 raw 1182 LZMA
fallback/postcar 0x147c00 stage 57876 none
fallback/payload 0x155e80 simple elf 1966159 none ← UEFI Payload
bootblock 0xc5ffc0 bootblock 28672 none
踩坑总结
| 问题 | 症状 | 解决方案 |
|---|---|---|
| GitHub TLS 失败 | git clone 卡住或报 GnuTLS 错误 |
GIT_HTTP_VERSION=HTTP/1.1 |
| coreboot.org 403 | crossgcc 下载失败 | 预缓存所有 tarball |
| binutils hash 不匹配 | hash mismatch 校验失败 |
从 sourceware.org 下载,不用 GNU mirror |
git describe 失败 |
shallow clone 没有 tag | 加 --always 参数 |
| BAT0 整体隐藏 | Object does not exist (BAT0) |
改用 _STA=0 代替 #ifndef 包裹 |
_STA 重复定义 |
Name already exists in scope |
修改原有 _STA,不新增 |
| ECPD 前向引用 | Object does not exist (ECPD) |
用 CondRefOf 包裹 |
| FV 容量溢出 | fv image size exceeds set size |
FDF 中 FD_SIZE 增大到 9MB |
| 4K 屏幕显示小框 | 开机 Logo 只占屏幕中间一小块 | EDK2 DSC 中 PcdVideo 从 1280×800 改为 0(自动检测原生分辨率) |
| 4K BMP 塞不进 ROM | 3840×2160 BMP 约 24MB > 16MB ROM | BMP 做小图 400×300,4K 全屏由 GOP 黑色背景填充 |
| iPXE git stash 冲突 | Your local changes would be overwritten by checkout |
git stash drop + git checkout coreboot |
注意事项
- ⚠️ 此固件为实验性质,刷写前必须用 programmer 备份原厂固件
- ⚠️ 不要盲目刷写,保留回滚方案
- 桌面机隐藏电池设备后,Windows 不再显示电池图标,也不会启用笔记本省电策略
RTL5682CID 可能帮助 macOS 识别声卡,但不保证完整驱动支持- 后续若需更新,只需
git fetch更新 coreboot 源码,重新应用补丁即可
参考链接
- MrChromebox coreboot: https://github.com/MrChromebox/coreboot
- Builder 仓库: https://github.com/rothdren-lion/noibat-bios-builder
- coreboot 官方文档: https://doc.coreboot.org/
by 数码罗记 · godsun.pro