📖前言
真实产线场景往往是这样:你手头有一块Coffee Lake / Whiskey Lake工控主板,厂商只给了一个.ROM,而你需要——
- 给自研板卡挂一个ACPI设备;
- 补一段唤醒逻辑、温度上报方法;
- 让OS侧驱动能通过_DSM拿到板卡私有配置。
这些需求的答案都指向同一件事:往固件里加一张自己的SSDT。
本期全程基于AMI Aptio(V为例,兼容说明Aptio 4):写ASL →编译→封装成AMI标准模块五件套→编进ROM →MMTOOL验证→ AFU刷写真机→ RU / Linux / Windows三层确认。每一步都是量产姿势。
0背景知识:ACPI / ASL / AML / DSDT / SSDT
老规矩,先把概念钉死:
ASL(源代码,人写) |
│ iasl 编译 |
▼ |
AML(字节码,机器"读") |
│ 塞进 |
▼ |
DSDT / SSDT(ACPI 表) |
│ 固件启动时递给 OS |
▼ |
OS 里的 AML 解释器逐条执行 |
(Windows 内置解释器 / Linux 的 ACPICA 子系统) |
ACPI表家族:
RSDP(根指针:固件留给 OS 的"入口纸条") |
└── XSDT(表目录) |
├── FACP 电源管理总开关 |
├── DSDT 主描述表:整机"户口本",一块主板一份 |
├── SSDT ★ 副表:今天的"外挂",想加就加 |
├── APIC 中断控制器 |
├── MCFG PCIe 配置空间基址 |
└── HPET / BGRT / … |
三个关键认知:
- AML在OS里执行,不在固件里。固件只是“投递员”——把表放进内存、把指针告诉OS。AMI Aptio源码树里那些平台自带的.asl文件(DSDT等),最终也是被编译后随镜像投递。
- 加SSDT,别动DSDT。AMI项目的DSDT是整包生成、跟芯片组代码强绑定的,侵入式修改维护噩梦;SSDT是即插即用的补充表,OS会把DSDT +所有SSDT合并进同一命名空间,效果等价。
- ASL名字规则:对象名最多4字符;下划线_开头(_HID、_STA…)是规范保留名,不能自己发明。
2准备工作
2.1 AMI Aptio项目包(公司授权交付)
AMI源码是授权+ NDA交付的,相信在座各位手里都有公司给的项目包(本文以Aptio V项目树为基准)。
2.2工具清单
工具 | 用途 | 来源 |
iasl | 编译/反汇编ASL | ACPICA官网,或AMI工具合集自带(AFU/AMIBCP/MMTOOL那一套里就有IASL.exe) |
build(build.bat) | 编译Aptio项目 | 项目包自带 |
MMTOOL | 查看/抽取/替换ROM里的FFS模块 | AMI工具合集 |
AFU(AFUWINx64 / AFUDOS / AFULNX) | 刷写固件 | AMI工具合集 |
RU.EXE | 不进OS直接看ACPI表/寄存器 | AMI工具合集 |
USB转TTL串口线 | 看DEBUG日志(Aptio走串口) | 淘宝20块 |
编程器(DediProg等) | 💀救砖用,强烈建议备着 | 同上 |
2.3硬件
一块可以随便折腾的开发板(示例:Coffee Lake工控板)。
3实战总览:我们要做什么
目标:在固件里添加自定义ACPI设备MYCO0001(一段MMIO寄存器+若干方法),最终在Linux里看到:
$ls/sys/bus/acpi/devices/ |
MYCO0001:00 PNP0103:00 PNP0C01:00 ... |
AMI平台的全流程:
① 写 SsdtDemo.asl |
│ iasl 编译 + acpiexec 自测 |
▼ |
② SsdtDemo.aml →(iasl -tc)→ SsdtDemoHex.h(C 数组) |
│ |
▼ |
③ 封装成 AMI 模块五件套(.c/.dxs/.cif/.mak/.sdl) |
│ 拷进项目模块树 + SDL 使能 |
▼ |
④ build 编译出 ROM |
│ |
▼ |
⑤ MMTOOL 打开 ROM,按 GUID 找到我们的模块(上机前先自证) |
│ |
▼ |
⑥ AFU 刷写真机 → RU / Linux / Windows 三层验证 |
熟悉本系列的老读者会发现:相比DXE阶段的其他模块,ACPI模块最大的特点是“固件侧只管投递,执行发生在OS”——这决定了我们验证工作的重心。
4源码编写步骤及解析
4.1 第一步:写 ASL 文件(逐行精讲)
在模块目录(下一步建立)里新建SsdtDemo.asl:
/* |