riplatt/truenas-rn426-panel
GitHub: riplatt/truenas-rn426-panel
纯 Python 用户空间前面板驱动,让运行 TrueNAS SCALE 的 NETGEAR ReadyNAS RN426 等机型的 LCD 屏幕和导航按钮恢复正常工作。
Stars: 0 | Forks: 0
# truenas-rn426-panel
这是一个前面板驱动程序,能让运行 **TrueNAS SCALE** 的 **NETGEAR ReadyNAS RN426**(以及共用同一前面板的同类机型 RN526 / RN626X)上的 **LCD 和导航按钮重获新生**。
当你在该硬件上安装 TrueNAS 时,小巧的前置显示屏会一直冻结在 **`Booting...`** 状态,按钮也毫无反应——因为 TrueNAS 没有提供适用于 NETGEAR 前面板的驱动程序。本项目正是该驱动程序,它通过逆向工程原厂 ReadyNAS 固件实现,并完全使用纯 Python 从头重写(无需 kernel module,也无需编译辅助程序)。

## 功能
- 驱动 128×32 **SSD1305 图形 LCD**(这是一块带有 SSD1305 级控制器的 LCD 面板;NETGEAR 的代码称其为 "oled")。
- 读取 **五向导航按钮**(上 / 下 / 左 / 右 / 中)。
- 显示可通过按钮循环切换的轮播信息**页面**:
1. 主机名 + IP
2. 存储池名称、健康状态、容量
3. CPU 温度 + 机箱风扇 RPM
4. 运行时间 + 平均负载
- 在可配置的空闲超时时间后(默认 90 秒)**自动息屏**,以避免图像残留/烧屏,并在按下任意按钮时唤醒。
- 作为 systemd 服务安装,**可在重启和 TrueNAS 更新后保留**(通过 TrueNAS 的 config-DB 初始化脚本注册,就像风扇控制守护进程一样)。
## 工作原理(简述)
- LCD 采用的是 **基于 Intel Denverton SoC GPIO 焊盘的 bit-bang SPI**,通过 `/dev/mem`(PADCFG_DW0 寄存器)直接写入。暴露这些寄存器的 P2SB 窗口通过 `/dev/port` 进行纯 Python 的 PCI 配置写入来取消隐藏——无需辅助二进制程序。
- 按钮连接在 Intel **i801 SMBus** 的**前面板 MSP430 微控制器**上;驱动程序通过 `/dev/i2c` 读取其 `reg 0x04` 按钮位图。它**不会**轮询 i2c(因为久而久之这会破坏 MCU 的按钮扫描)。相反,它会监视 MCU 的**中断线**——这是一个通过 `/dev/mem` 读取的 Denverton SoC GPIO 焊盘(`0xFDC50570`)——并且仅在发出按键信号时才读取 `reg 0x04`。这实现了类似中断的响应速度,完全在用户空间运行,无需 kernel module。详见 [`docs/buttons-protocol.md`](docs/buttons-protocol.md)。
完整的细节、寄存器映射以及逆向工程过程详见 [`docs/`](docs/)。
## 环境要求
- 运行 **TrueNAS SCALE** 的 ReadyNAS **RN426 / RN526 / RN626X**。
- `python3` + **Pillow** (`python3-pil`) 以及 **DejaVu** 字体——这两者均随 TrueNAS SCALE 提供。
- 内核模块 `i2c-dev` 和 `i2c-i801`(由安装程序自动加载)。
- 用于安装的存储池(根文件系统在更新时会被重置,因此文件需存放在存储池中,且服务需注册在配置数据库中)。
## 安装说明
```
git clone https://github.com/riplatt/truenas-rn426-panel.git
cd truenas-rn426-panel
sudo ./install.sh /mnt//rn426-panel
```
`install.sh` 会将驱动程序复制到指定目录,加载 i2c 模块,在 TrueNAS 配置数据库中注册一个 **POSTINIT** 初始化脚本,并启动该服务。具体步骤请查看脚本,这些步骤完全是可逆的。
卸载方法:`sudo ./install.sh --uninstall /mnt//rn426-panel`。
## 使用方法
```
# 该服务会自动运行;手动控制:
sudo systemctl status rn426-panel
python3 rn426_panel.py sleep # blank the display now
python3 rn426_panel.py wake # re-init / wake it
python3 rn426_panel.py run # run the loop in the foreground
RN_SLEEP=120 ... # env var: idle seconds before sleep (0 = never)
```
通过编辑 `rn426_panel.py` 中的 `page_*()` 函数和 `PAGES` 列表来自定义页面。
## 重要注意事项
- **i2c 总线编号在重启后并不稳定**——i801 和 iSMT SMBus 适配器可能会在 `i2c-0` 和 `i2c-1` 之间发生互换。驱动程序会按名称查找 i801 总线,因此不要硬编码总线编号。
- **切勿写入 MSP430 的 `reg 0x02`**(其 LED/控制寄存器)。在此固件上,该寄存器*也*控制着按钮扫描;一旦禁用它,按钮将停止响应,并且**只能通过完全断电重启来恢复——热重启是不够的**(因为前面板由待机电源供电)。本驱动程序对 MCU 采取严格的只读模式。如果你的按钮失灵,请进行一次彻底的断电再开机。
- LCD 的 `EN` 线控制着面板电源,因此从睡眠状态唤醒时会进行全面的重新初始化,而不仅仅是发送开启显示的指令。
## 移植到其他 ReadyNAS 型号
该方法(逆向工程原厂固件的 `oled_probe` / `spi_send` / `i2cfb_reporter`,然后通过 `/dev/mem` 驱动焊盘)具有通用性。各型号专属的 GPIO 焊盘映射存在于固件中(查找 `rn426_8` / `rnx16` 配置结构体)。详见 [`docs/porting.md`](docs/porting.md)。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。本项目不附属于 NETGEAR 或 iXsystems,也未获得其认可。使用风险自负;本项目会直接操作 SoC 寄存器。
标签:GPIO, NAS, Python, TrueNAS, 云资产清单, 无后门, 硬件驱动, 系统运维, 逆向工具, 逆向工程