GodsQuantum/huawei-matebook-fingerprint-linux
GitHub: GodsQuantum/huawei-matebook-fingerprint-linux
该项目记录了 Goodix GXFP51A0 SPI 指纹传感器的 ACPI 资源并为 OpenGoodixSPI 驱动提供了 reset-GPIO 修复补丁,推进华为 MateBook 在 Linux 下的指纹适配工作。
Stars: 1 | Forks: 0
# Linux 下的 Goodix GXFP51A0 (SPI) — reset-GPIO 修复与发现
**硬件:** Huawei MateBook 13 2021 (`WRTB-WXX9`) · Goodix **GXFP51A0** SPI 指纹传感器(电源按钮集成) · Pop!_OS / kernel 7.0.11 · Secure Boot 关闭。
## TL;DR
这款笔记本电脑上的 Goodix **SPI** 指纹传感器在其 ACPI `_CRS` 中声明了一个 **reset/enable GPIO**,但**目前没有任何 Linux 代码驱动它**——无论是 [OpenGoodixSPI](https://github.com/PeshalaDilshan/OpenGoodixSPI) 还是 [goodix-fp-dump](https://github.com/goodix-fp-linux-dev/goodix-fp-dump)。此仓库:
- 记录了该传感器的确切 ACPI 资源(SPI 总线、IRQ、**reset GPIO = gpiochip0 line 264**)。
- 提供了一个**针对 OpenGoodixSPI 的补丁**,该补丁通过 ACPI GPIO 映射解析并触发该 reset GPIO 的脉冲。
- 报告了完整的测试矩阵以及剩余的阻碍。
**状态:** 该 reset 补丁*必要但不充分*。复位后,data-ready IRQ 开始触发(传感器有反应),但在测试的每种软件条件下,SPI 的 **MISO 始终保持常量 `0xFF`**。剩下的障碍是专有的唤醒 / bootloader / TLS 序列,实际上需要通过 **Windows 端的 SPI 抓取(逻辑分析仪)** 来进行逆向工程。
## 为什么这很重要
整个 MateBook 13 2021 系列和许多 Honor MagicBook 型号都搭载了同类的 GXFP51A0 SPI 传感器。使 reset GPIO 生效是目前社区驱动程序缺失的一个具体、可重用的第一步。
## ACPI 事实(反编译的 DSDT)
设备 `\_SB.PCI0.SPI1.SPBA`,`_HID/_CID "GXFP51A0"`:
| 资源 | 值 |
| --- | --- |
| SPI 总线 | `\_SB.PCI0.SPI1`,10 MHz (`0x00989680`),Mode 0,4-wire |
| Data-ready IRQ | `GpioInt (Level, ActiveHigh, ExclusiveAndWake)` 位于 `\_SB.PCI0.GPI0`,引脚 `GNUM(0x04010010)` → kernel IRQ 144 |
| **Reset / enable** | `GpioIo (PullUp, IoRestrictionOutputOnly)` 位于 `\_SB.PCI0.GPI0`,引脚 `GNUM(0x04020008)` → **gpiochip0 line 264** |
| `_INI` | `SHPO(0x04010010,1)`,`SHPO(0x04020008,1)` → 两个焊盘均设置为 GPIO 模式(主机端可驱动) |
| 电源管理 | 传感器节点**没有 `_PSC`/`_PS0`**(`power_state` 为空,`_STA` = `0x0F`);父设备 SPI1 已处于 D0 |
该传感器是**电源按钮集成**的。它在系统开机时就会通电(用于 Windows 开机身份验证),因此阻碍*不是*电源轨被切断——唯一的主机端控制门就是上述的 reset GPIO。
## 修复方案(针对 OpenGoodixSPI 的补丁)
直接使用 `devm_gpiod_get_index(dev, NULL, 0, ...)` 会返回 `-ENOENT`,因为在 `_CRS` 顺序中,**GpioInt 是索引 0**,而 **GpioIo (reset) 是索引 1**。必须通过 ACPI GPIO 映射在 CRS 索引 1 处请求 reset:
```
#include
static const struct acpi_gpio_params opengoodix_reset_gpio = { 1, 0, false }; /* crs_entry_index = 1 */
static const struct acpi_gpio_mapping opengoodix_gpios[] = {
{ "reset-gpios", &opengoodix_reset_gpio, 1 },
{ }
};
/* in opengoodix_probe(), right after spi_set_drvdata(spi, data): */
ret = devm_acpi_dev_add_driver_gpios(dev, opengoodix_gpios);
if (ret)
dev_warn(dev, "add_driver_gpios failed: %d\n", ret);
data->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (!IS_ERR(data->reset_gpio)) {
dev_info(dev, "Reset GPIO acquired, pulsing\n");
gpiod_set_value_cansleep(data->reset_gpio, 0); msleep(10);
gpiod_set_value_cansleep(data->reset_gpio, 1); msleep(100);
} else {
dev_warn(dev, "No reset GPIO (%ld)\n", PTR_ERR(data->reset_gpio));
data->reset_gpio = NULL;
}
```
在 [`patches/apply-reset-gpio.py`](patches/apply-reset-gpio.py) 中提供了一个可以直接运行的修补脚本,它可以将此修改应用到一个全新的 `OpenGoodixSPI/driver/opengoodixspi.c` 上。
应用补丁后,`dmesg` 会显示 `Reset GPIO acquired, pulsing`,并且 data-ready IRQ (144) 会在脉冲发生后开始触发——这证实了传感器的电气状态发生了变化。
## 测试矩阵(所有结果 → MISO `0xFF`)
已通过 goodix-fp-dump 的 `driver_51x0_spi` 在 `/dev/spidev0.0` 上独立验证:
| 条件 | 结果 |
| --- | --- |
| 释放 reset / 保持高电平 (`gpioset gpiochip0 264=1`) | `0xFF` |
| 保持低电平 reset (`gpioset gpiochip0 264=0`) | `0xFF` |
| SPI @ 10 MHz 和 @ 1 MHz | `0xFF` |
| `nop()`,`enable_chip()`,`firmware_version()` | `0xFF` |
即使在全双工传输的**写入阶段**,MISO 也是 `0xFF` → 传感器芯片并未驱动数据线,也就是说,这不仅仅是读取/时序不匹配的问题。
## 复现
```
# 1. 将 spidev 绑定到传感器
echo spidev | sudo tee /sys/bus/spi/devices/spi-GXFP51A0:00/driver_override
echo spi-GXFP51A0:00 | sudo tee /sys/bus/spi/drivers/spidev/bind
# 2. 导出传感器的 ACPI _CRS
cd /tmp && sudo acpidump -b && iasl -d dsdt.dat >/dev/null 2>&1
awk '/GXFP51A0/,0' /tmp/dsdt.dsl | head -120
# 3. 打补丁 + 构建 + 加载 OpenGoodixSPI(见 patches/)
```
## 路线图 / 寻求帮助
1. 对 Goodix Windows 驱动程序(`gfspi.dll` / `AlgoMilan.dll`,v1.1.124.12)进行**逻辑分析仪或 Windows SPI 抓取**,涵盖从冷启动到首次响应的过程——以还原唤醒/上电时序以及 bootloader 固件上传的帧结构。
2. 根据该抓取结果实现 `opengoodix_load_firmware`(目前是一个 TODO 桩)。
3. 将读取操作连接到真实的 data-ready GpioInt(CRS 索引 0),而不是盲目的轮询。
4. **未尝试的手段:** 在任何 chip-id 读取*之前*,发送文档中记载的 `0xB0` **Wake** 命令(根据 OpenGoodixSPI 的说明,它会“将 MISO 拉低”并且“必须在发送其他命令之前发送”)。这两个驱动程序都没有隔离此前导码;如果在 `0xB0` 之后 MISO 立即降至 `0xFF` 以下,那这就是第一个真实的响应。
欢迎贡献——请提交一个 issue 并附上您的笔记本电脑型号、`dmesg` 和 `_CRS`。
## 鸣谢与参考
- OpenGoodixSPI — https://github.com/PeshalaDilshan/OpenGoodixSPI
- goodix-fp-dump — https://github.com/goodix-fp-linux-dev/goodix-fp-dump
- libfprint issue #112 (GXFP SPI) — https://gitlab.freedesktop.org/libfprint/libfprint/-/issues/112
- egormanga/goodix-spi-protocol — https://github.com/egormanga/goodix-spi-protocol
- tlambertz/goodix-fingerprint-reversing — https://github.com/tlambertz/goodix-fingerprint-reversing
- nekr0z/linux-on-huawei-matebook-13-2019 — https://github.com/nekr0z/linux-on-huawei-matebook-13-2019
## 许可证
GPL-2.0-only(该内核补丁继承了 OpenGoodixSPI 的许可证)。请参阅 [LICENSE](LICENSE)。
标签:ACPI, 云资产清单, 安全渗透, 指纹传感器, 硬件驱动, 逆向工具, 逆向工程