NanoKVM Lite 无画面排障记录:采集芯片假死、OTA 失效与 HDCP 嫌疑

NanoKVM Lite 接 Mac mini(M1)做带外管理,出现两个问题:Web 界面的 OTA 升级无效;HDMI 连接正常但没有画面。最终固件从 1.x 升到 2.5.2,画面恢复。过程记录如下。

OTA 升级失效

设置页点击升级后接口很快返回 {"code":0,"msg":"success"},但版本号不变。

在设备终端监控升级全过程:POST /api/firmware/update 返回成功的前后,/tmp 用量没有任何变化(df 持续观测),/kvmapp 文件时间戳不变,唯一的变化是 /tmp/firmware/ 下出现一个 0 字节的 libmaixcam_lib.so。设备网络正常,CDN 地址可达。结论:2024-07 版 1.x 固件的 OTA 逻辑已失效,且接口假报成功,没有任何报错暴露这一点。

按官方 update-nanokvm.py 的逻辑手动执行升级:

1
2
3
4
5
6
7
8
9
10
11
12
cd /root
curl -m 600 -o latest.zip "https://cdn.sipeed.com/nanokvm/latest.zip"
mkdir -p .kvm-cache && cd .kvm-cache && unzip -q /root/latest.zip && cd /root
/etc/init.d/S95webkvm stop # 停掉老固件的服务
mv /kvmapp /root/old # 备份,可回滚
mv /root/.kvm-cache/latest /kvmapp
chmod -R 755 /kvmapp
rm -f /etc/init.d/S95webkvm
cp /kvmapp/jpg_stream/S95nanokvm /etc/init.d/S95nanokvm
chmod 755 /etc/init.d/S95nanokvm
rm -rf /kvmapp/jpg_stream
sync && reboot

两个注意点:

  1. 解压目录不要放 /tmp:它是约 79MB 的 tmpfs,升级包解压后约 65MB,加上 zip 本身会写爆。放 rootfs(如 /root)。
  2. 新版首次启动检测到 /kvmapp/kvm_new_app 标志会自动执行二次迁移(替换全套 init 脚本、更新 MIPI 采集内核驱动 soph_mipi_rx.ko),并再重启一次。设备连续重启两次属于正常流程。

升级后 /api/application/version 返回 2.4.3(后续又通过 2.4.3 的离线更新接口升级到 2.5.2,接口直接接受官方 release 的 nanokvm_2.5.2.tar.gz)。

无画面排查

升级后界面提示”未检测到 HDMI 信号”。自底向上排查:

  • kvm_system、NanoKVM-Server 进程正常;
  • 内核驱动 soph_mipi_rx.ko 已随迁移更新且加载正常;
  • 采集芯片 LT6911C 在 I2C 总线 4 的 0x2b/0x2c 地址应答正常;
  • VI 子系统帧率为 0。

故障点收敛到 LT6911C。先停掉 kvm_system(避免并发 I2C 访问污染读数),用 i2ctransfer 直读芯片寄存器:

1
2
3
4
5
6
7
8
9
10
# TMDS 输入时钟:页 0xa0 触发测量,页 0xb8 读三字节
i2ctransfer -y 4 w2@0x2b 0xff 0xa0; i2ctransfer -y 4 w2@0x2b 0x34 0x0b; sleep 0.3
i2ctransfer -y 4 w2@0x2b 0xff 0xb8; i2ctransfer -y 4 w1@0x2b 0xb1 r3

# RX 端锁定的分辨率:页 0xd2 触发,读 0x96/0x97(高)、0x8b/0x8c(宽,需×2)
i2ctransfer -y 4 w2@0x2b 0xff 0xd2; i2ctransfer -y 4 w2@0x2b 0x83 0x11; sleep 0.2
i2ctransfer -y 4 w1@0x2b 0x96 r2; i2ctransfer -y 4 w1@0x2b 0x8b r2

# CSI 输出端实际发出的分辨率:页 0xc2,读 0x06(高)、0x38(宽)
i2ctransfer -y 4 w2@0x2b 0xff 0xc2; i2ctransfer -y 4 w1@0x2b 0x06 r2; i2ctransfer -y 4 w1@0x2b 0x38 r2

结果:

  • TMDS 输入时钟 148.5MHz,多次测量稳定——Mac 正在输出标准 1080p60,线缆和 DDC 握手正常;
  • RX 端锁定 1920×1080——芯片接收引擎正常;
  • CSI 输出 0×0——芯片没有向后级转发任何帧。

即:信号到达且被正确接收,但转发环节没有输出。

HDCP 假设与 EDID 处理

“收到画面但拒绝转发”有一个具体的嫌疑机制:HDCP。

macOS 对 EDID 中带有 CEA 扩展(声明 HDMI 能力)的显示设备会主动发起 HDCP 协商,为 DRM 内容预建加密链路。协商走 DDC 地址 0x74,LT6911C 内置 HDCP 引擎会应答。HDCP 要求接收端内置授权密钥(生产时烧录进芯片 flash 的密钥区),而 0x74 的应答是硬件行为,不校验密钥内容。如果密钥区为空或损坏:Mac 认为链路支持 HDCP 并发送加密流,芯片解密失败,按 HDCP 规范不允许输出解密失败的像素,于是全部丢弃。链路时钟正常、分辨率可测、画面全黑,与观测吻合。

作为对照,无 HDCP 硬件的采集芯片(如 TC358743)不应答 0x74,Mac 探测失败后退回明文输出,反而不出现这类问题。

EDID 存在 LT6911C 自己的 flash 里,与主控固件相互独立,OTA 升级不涉及它。处理尝试:

1
echo Y | /kvmapp/system/tool/nanokvm_update_edid /kvmapp/system/tool/E21_NanoKVM.bin

先后刷了两个版本:官方 E21(带 CEA 扩展),以及一个自制的 DVI 变体(去掉 CEA 扩展,使 Mac 按纯 DVI 显示器处理、不发起 HDCP;做法与成品文件见文末附录)。刷 DVI 版后有一个可观测的变化:Mac 的输出时钟从约 142.5MHz 切换到标准 148.5MHz,说明 EDID 握手链路正常,Mac 确实在按 EDID 内容调整输出。

但画面仍未恢复。期间还尝试过 GPIO 硬复位、I2C 软复位、完整重初始化序列(页 0x80:0x5A=0x88 停 → 0xee=0x00 关 → 0xee=0x01 开 → 0x5A=0x80 启),均无效。

恢复

最终生效的操作:把 NanoKVM 整机断电,重新上电。画面立即恢复。

原因:LT6911C 独立供电。主控 SG2002 执行 reboot 不会切断采集芯片的电源,升级过程中设备虽然重启过两次,芯片的异常状态一直被保持。GPIO 复位和 I2C 复位只复位部分逻辑,只有断电能让芯片冷启动:重新加载 EDID、完整初始化 RX/TX 引擎。

复盘:根因

按证据强度分三层。

观测事实:TMDS 时钟稳定、RX 锁定 1080p、CSI 输出为 0;GPIO 复位与主控重启均无效;整机断电冷启动后恢复。

推断:LT6911C 进入了一种异常状态——接收正常但不转发——该状态只能被芯片断电清除。

无法确证的部分:异常状态的本质是”HDCP 密钥失效导致解密掐流”还是”芯片固件卡死”。LT6911C 不公开 HDCP 状态寄存器,没有直接证据;且最后生效的那次断电与 DVI EDID 生效同时发生,两个变量未能隔离。

由此回答”不改 EDID 能否解决”:大概率能。刷写前没有读取过原始 EDID,”EDID 损坏”从无直接证据;第一次刷官方 E21 + 断电后画面仍无变化,说明刷 EDID 单独不构成修复。但换 DVI EDID 后 Mac 的输出时序确实发生了变化,也不能完全排除 EDID 因素。两者各自的贡献已无法事后分离。

官方 issue 区的相关情况:

  • #822:Cube(LT6911UXC,同家族芯片)接 Apple Silicon Mac,HDCP 认证无法完成,macOS 每约 2 秒重试一轮,严重时导致 WindowServer 看门狗超时、内核 panic。作者证实有源 HDMI 分配器可在输入侧终结 HDCP、使风暴归零。其”advertise-but-fail”分析与本文的假设一致。
  • #875:Cube 在 2.4.3/2.5.0 上采集零帧(VIFPS 0),与本文”CSI 0×0”症状相同。
  • #890:Cube 的 2.5.0 回归中明确排除了 EDID 因素——侧面说明 EDID 未必是关键变量。
  • 我们以 Lite + LT6911C + M1 Mac mini 的完整证据链提了 #951。”DVI EDID 绕过 HDCP”这个具体角度此前无人报告。

经验

  1. 采集芯片独立供电的设备,reboot 不等于断电。排查应把整机断电放在第一步,而不是最后一步。
  2. OTA”假成功”的鉴别方法:不要看界面提示,去终端确认升级期间有真实的下载活动。
  3. 无画面排查顺序:/kvmapp/kvm/state → I2C 探测芯片 → 测 TMDS 时钟(确认源在输出)→ 读 RX 锁定分辨率(确认芯片收到)→ 读 CSI 输出(确认芯片转发)。三层分开,故障点立刻收敛。
  4. Mac 的两个坑:macOS 会主动发起 HDCP 协商(Windows 只在播放 DRM 内容时才发起,因此这类问题集中出现在 Mac 上);NanoKVM 的 USB 复合设备(HID+RNDIS+U盘)会被 macOS 配件安全策略整体拦截,需要用物理鼠标批准一次,或在设置中改为”总是允许”。
  5. 设备换网后找不到 IP 时不必扫网段:mDNS 地址 kvm-xxxx.local 可直接访问。

附录:EDID 成品文件与复现方法

LT6911C 没有”DVI 模式”开关——NanoKVM 官方源码、Linux 主线驱动和社区逆向资料中都不存在模式切换寄存器(完整功能规格书需向 Lontium 签 NDA 获取)。芯片对信号源呈现的身份完全由 EDID 内容决定,因此”DVI 化”= 换一份不含 CEA 扩展的 EDID。以下两个文件可直接下载:

文件 说明 SHA-256
E21_NanoKVM.bin 官方原版(带 CEA 扩展),取自官方固件包,未修改 526e33a7…742146e
E21_NanoKVM_DVI.bin DVI 变体(无 CEA 扩展,Mac 不发起 HDCP) df21b378…fc77c56

两个文件仅差三处:

1
2
3
字节 126:     0x01 → 0x00    扩展块计数置 0
字节 127: 0xf5 → 0xf6 基础块校验和重算(每 128 字节块求和须 ≡ 0 mod 256)
字节 128–255: CEA 扩展块 → 全部清零

自行制作(或验证成品)只需三行 Python:

1
2
3
4
5
data = bytearray(open('E21_NanoKVM.bin', 'rb').read())
data[126] = 0x00 # 无扩展块
data[127] = (data[127] + 1) % 256 # 校验和补偿
data[128:] = bytes(128) # 清掉 CEA 块
open('E21_NanoKVM_DVI.bin', 'wb').write(bytes(data))

烧录与生效:

1
2
3
4
5
# 1. 文件传到设备(scp 或设备上直接 curl 下载本文附件)
# 2. 官方工具刷写(工具自带校验和检查,校验不过会拒绝写入)
echo Y | /kvmapp/system/tool/nanokvm_update_edid /root/E21_NanoKVM_DVI.bin
# 3. 断电重启 NanoKVM(拔电再插回)——LT6911C 冷启动时才重新加载 EDID
# 4. Mac 侧重新插拔 HDMI,或在"系统设置→显示器"触发重新检测

注意事项:

  • DVI 变体不再声明 HDMI 音频能力(NanoKVM 不采集音频,对 KVM 用途无影响);
  • 刷错 EDID 会导致 Mac 检测不到显示器,需刷回官方原版恢复;
  • 刷写前建议先读回当前内容留底(同一工具支持读回校验);
  • 这套操作针对”Mac 不输出或输出加密流”类问题;如果故障是采集芯片假死(CSI 零输出),EDID 无效,需要断电。两者的鉴别方法见上文排查部分。

参考