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, 云资产清单, 安全渗透, 指纹传感器, 硬件驱动, 逆向工具, 逆向工程