# Kindle Voyage 5.13.6 白屏/KUAL/SSH 交接文档 本文记录 2026-03-15 到 2026-03-17 这轮 dashboard 调试在后半段进入的异常状态,目标是给下一次接手排障的人一个明确起点,避免继续沿着已经证伪或高风险的路径重复试错。 ## 当前交接状态 截至本次更新时,设备已经不再停留在“完全卡死且无法 SSH”的状态,结论也分成了两部分: - 已修住的: - `calendar -> 主页 -> KUAL -> 回主页` 已能正常工作 - `ssh kindle` 已恢复可用 - 当前默认架构已切到“保留原生 UI 栈”的 overlay 模式 - 仍未完全收口的: - 从 `KUAL -> Kindle Dashboard` 进入 dashboard 时,仍出现过白屏 - 白屏出现时,dashboard 本身往往没有真正接管成功,更像是 `framework/KUAL` 启动链在中途被打断 补充记录一个当前仍未修住、但边界已经比较清楚的问题: - 从 `KUAL` 进入 dashboard 后,再尝试回到 dashboard / KUAL 的原生 UI 路径,仍可能落入白屏 - 这个问题不应再继续归因到背景图、时钟或页面布局 - 当前更合理的判断,仍然是 `KUAL -> start.sh -> dash.sh` 的切换链路不稳定 - `2026-03-17` 这轮新增验证还能确认:直接碰 `blanket` 或强拉 `booklet.home`,会进一步触发 `blanket / cvm` 崩溃 这份文档只记录当前交接结论,不再继续尝试修复。 ## 已确认的事实 ### 1. `Dashboard Debug On` 已能阻止自动挂起 这部分在设备可连 SSH 时已经实机验证通过: - [dash/src/debug-on.sh](/Users/gavin/kindle-dash/dash/src/debug-on.sh) 现在会: - 把 `DISABLE_SYSTEM_SUSPEND=true` 写入 `local/env.sh` - 自动重启 dashboard - 日志里已经出现过: ```text Skipping system suspend, sleeping for 40s instead ``` 所以“点 `Dashboard Debug On` 之后 3 秒就休眠”这个问题,本轮已经修住。 ### 2. 旧架构里,`dashboard` 不是可交互界面 旧实现里,dashboard 启动后会主动停掉 Kindle 的前台 UI: - [dash/src/dash.sh](/Users/gavin/kindle-dash/dash/src/dash.sh#L50) 调用 `stop_framework` - [dash/src/dash.sh](/Users/gavin/kindle-dash/dash/src/dash.sh#L51) 停掉 `webreader` 这意味着: - 进入 dashboard 之后,不应再期望当前屏幕仍然像普通 Kindle 页面那样可点击 - 也不应再期待“从 dashboard 直接返回刚才那个 KUAL 页面” 补充: - 截至 `2026-03-17`,默认实现已经改成 `KEEP_NATIVE_UI_STACK_RUNNING=true` - 也就是保留 `framework / webreader` 存活,把 dashboard 当成覆盖显示层 - 在这条新路径上,`calendar -> 主页 -> KUAL -> 回主页` 已完成实机验证 ### 3. 顶栏遮罩不处理触摸 右上角状态栏遮罩逻辑在: - [dash/src/dash.sh](/Users/gavin/kindle-dash/dash/src/dash.sh#L121) 它只是调用 `fbink` 在帧缓冲上画白色矩形,不负责输入,也不会接管触摸事件。因此: - “点不到 KUAL” 不是顶栏遮罩造成的 - 真正相关的是 `framework/webreader` 被停掉 ### 4. `stop.sh` 现在分成两种退出路径 当前 [dash/src/stop.sh](/Users/gavin/kindle-dash/dash/src/stop.sh) 已改成: - 默认 overlay 模式: - 停掉 `dash.sh` - 清掉 `preventScreenSaver` - 停掉主题菜单和右下角长按监听 - 如果底层当前是 `KUAL`,再通过 `appmgrd stop` 把它正常退回首页 - 旧架构兼容模式: - 停掉 `dash.sh` - 清掉 `preventScreenSaver` - 停干净 `framework / webreader / cvm` - 再按顺序拉起 `framework` - 等 `cvm` 回来后启动 `webreader` 也就是说它的职责是: - 让 Kindle 从 dashboard 安全退回原生 UI 不是: - 直接把 KUAL booklet 弹出来 - 也不是走实验性的“快切换” 补充: - 本轮新试过的“快路径”已经撤回 - 直接碰 `blanket` 或尝试 shell 里强拉 `booklet.home`,都可能把 `blanket / cvm` 打崩 - 当前 Voyage 5.13.6 仍以稳定恢复优先,快速切换需要改入口架构,不能继续堆在 `stop.sh` 上 补充一点:在白屏恢复过程中,`stop.sh` 已经比旧版稳定很多,但仍存在一种残留状态: - `framework` 和 `cvm` 已回来了 - `webreader` 可能还停在 `stop/waiting` 针对这个问题,`stop.sh` 现在已经补成“循环检查并补拉起 `webreader`,直到连续几次都保持 `start/running`”。 如果未来仍然遇到个别恢复失败,再把 `/sbin/start webreader` 当作人工兜底,不再作为默认恢复步骤。 ### 5. 直接 `booklet run` 或手动 `blanket unload` 的试探命令不安全 本轮为了验证能否从 shell 里直接拉起主页、KUAL,或者手动剥掉前台遮罩,试过几类命令: ```sh lipc-set-prop com.lab126.booklet run "app://com.lab126.booklet.home" lipc-set-prop com.lab126.booklet run "com.mobileread.ixtab.kindlelauncher.KualBooklet" lipc-set-prop com.lab126.blanket unload splash lipc-set-prop com.lab126.blanket unload screensaver ``` 这条路不稳定,已经触发过 `cvm` 崩溃打包。设备上看到过: - `/mnt/us/documents/cvm_2886_..._crash_Mar_15_14.14.19_2026.tgz` - `/mnt/us/documents/cvm_5551_..._crash_Mar_15_14.18.54_2026.tgz` - `/mnt/us/documents/cvm_18914_..._crash_Mar_17_09.16.13_2026.tgz` - `/mnt/us/documents/cvm_22294_..._crash_Mar_17_09.21.03_2026.tgz` - `/mnt/us/documents/blanket_13032_..._crash_Mar_17_09.10.13_2026.tgz` 因此下次接手时,不要再直接复用这些命令,也不要把“先手动卸掉 `blanket` 再看前台会不会回来”当成安全恢复手段。 ### 6. dashboard 本身可以工作,失败更像发生在 KUAL 启动路径 本轮已经验证过: - 通过 SSH 直接前台运行 `DEBUG=true ./start.sh`,dashboard 可以正常渲染 - 时钟、背景图、顶栏遮罩都能按预期执行 - 前台日志里可以看到正常的刷新过程 这说明: - dashboard 渲染逻辑本身不是当前白屏问题的主因 - 真正未解的是 `KUAL -> start.sh -> dash.sh` 这条非调试、后台化启动路径 ### 7. 白屏时,帧缓冲本身就是白的,不是单纯 e-ink 残影 本轮抓过多次 `fbgrab`: - `tmp/current-ui.png` - `tmp/ui-restart-screen.png` - `tmp/ui-after-power-cycle.png` 这些截图都是真正的纯白图,不是“系统其实起来了,只是屏幕没刷新”。因此: - 白屏发生时,不能只从物理屏幕角度判断 - 需要继续围绕 `framework / cvm / webreader / dash.sh` 的实际进程状态排查 ### 8. 日志证据表明:KUAL 切到 dashboard 的过程中,framework 主进程被 TERM 这轮从 `/var/log/messages` 里已经看到关键序列: - KUAL booklet 被启动 - home booklet 被恢复 - 随后 `framework main process (...) killed by TERM signal` 这说明当前最可疑的点是: - KUAL 页面触发 dashboard 启动时,父 UI 进程在切换链路中被自己或系统杀掉 - dashboard 又没有在这之前稳定脱离 KUAL 会话 - 结果就是前台白屏,而不是正常切入 dashboard ## 本轮过程中已验证过的有效路径 在问题进一步收敛前,以下链路是验证过可工作的: ### 1. 背景图链路 - 网页导出 `1072x1448` 的 `8-bit grayscale PNG` - Kindle 直接显示这张背景图时,所见即所得 关键文件: - [calendar/dist/kindlebg.png](/Users/gavin/kindle-dash/calendar/dist/kindlebg.png) - [dash/src/local/fetch-dashboard.sh](/Users/gavin/kindle-dash/dash/src/local/fetch-dashboard.sh) ### 2. 本机时钟链路 黑块问题已经从“透明 PNG patch”切到“Lua 本机绘制”: - [dash/src/local/render-clock.lua](/Users/gavin/kindle-dash/dash/src/local/render-clock.lua) - [dash/src/local/render-clock.sh](/Users/gavin/kindle-dash/dash/src/local/render-clock.sh) 当设备 SSH 正常时,这条链路已经实机验证过: - 背景正常 - 时钟可叠加 - 不再出现整块黑色 patch ### 3. Wi-Fi SSH 链路 目前仍可用的稳定入口是: ```sh ssh kindle ``` 它依赖本机 `~/.ssh/config` 中的: - `HostName 192.168.72.3` - `IdentityFile ~/.ssh/id_ed25519_git` 这一条在本次文档更新时已经恢复。 ### 4. 直接从 SSH 前台启动 dashboard 当前唯一明确验证成功的 dashboard 启动方式是: ```sh ssh kindle 'cd /mnt/us/dashboard && DEBUG=true ./start.sh' ``` 这条路径的特点是: - `dash.sh` 以前台方式运行 - 不依赖 KUAL 页面还活着 - 能直接看到 shell trace 和实时日志 相对地: - 直接点 `KUAL -> Kindle Dashboard` - 或通过普通 `./start.sh` 后台起进程 这两条路径目前都没有被证明稳定。 ## 当前不要再做的事情 以下路径本轮已经证明风险高或收益低,下次接手前不要重复: 1. 不要再尝试“双击电源键 / 同时按翻页条”呼出 KUAL - 当前仓库没有任何这类按键绑定实现 - 这条路没有现成机制可用 2. 不要再尝试 `booklet run` 直接拉起主页或 KUAL - 已触发 `cvm` 崩溃 - 风险高于收益 3. 不要继续走“KUAL -> Dashboard -> 再返回 KUAL”的交互路径 - dashboard 启动后会停掉 `framework/webreader` - 从逻辑上这就不是一个受支持的返回路径 4. 不要把 `KUAL -> Kindle Dashboard` 当成当前可用入口 - 这正是现在仍会复现白屏的路径 - 问题还没有修住 ## 下一次接手的安全起点 下一次恢复排障时,请按这个顺序来: ### A. 先把设备恢复到正常 UI 1. 长按电源键约 40 秒重启 2. 先不要启动 dashboard 3. 先确认能正常回到 Kindle 首页 4. 再确认能正常打开 KUAL ### B. 再确认网络 只有在设备已经稳定回到正常 UI 后,才做这一步: ```sh ssh kindle ``` 如果仍然不通,再查: - Kindle 是否连回同一个主 Wi-Fi - IP 是否还是 `192.168.72.3` - DropBear 是否还在监听 `22` ### C. 重新进入 dashboard 时的推荐方式 恢复后如果还要继续调 dashboard,当前建议只走这条路径: ```sh ssh kindle 'cd /mnt/us/dashboard && DEBUG=true ./start.sh' ``` 原因: - 这条路径已经验证成功 - 可以直接看到日志 - 不依赖 KUAL 的 UI 切换链路 退出 dashboard 时: ```sh ssh kindle 'cd /mnt/us/dashboard && ./stop.sh' ``` 等几秒,让 UI 栈恢复,再从 Kindle 首页重新打开 KUAL。 如果执行完 `./stop.sh` 后主页仍然没有回来,再补: ```sh ssh kindle '/sbin/start webreader' ``` 不要从 dashboard 页面直接尝试回 KUAL。 ### D. 当前真正待修的点 下次接手时,排障目标应该收敛到这一条: - 为什么 `KUAL -> Kindle Dashboard` 会白屏,而 `ssh kindle 'DEBUG=true ./start.sh'` 却能正常显示 也就是说,重点应该放在: - KUAL 菜单动作 - `start.sh` 的后台脱离方式 - `framework` 被 TERM 的时机 而不是继续怀疑背景图、时钟绘制或顶栏遮罩。 进一步说,当前建议把这个遗留问题固定表述为: - “`KUAL -> Kindle Dashboard` 与 `dashboard -> 原生 UI/KUAL` 之间的边界切换不稳定,表现为白屏” 建议的修复方向是: 1. 不要让 KUAL 直接同步执行 `/mnt/us/dashboard/start.sh` 2. 改成由一个独立 wrapper 先脱离 KUAL / framework 会话,再延迟启动 dashboard 3. 继续保留 `ssh kindle 'cd /mnt/us/dashboard && DEBUG=true ./start.sh'` 作为唯一已验证稳定的进入方式 4. 继续保留 `./stop.sh` 作为唯一已验证稳定的退出恢复方式 截至 2026-03-18,这个修复方向已经按最小改动落地到仓库: 1. KUAL 顶层菜单改成 `Kindle Dashboard -> 主题列表` 2. 具体主题项调用 `/mnt/us/dashboard/launch-theme-from-kual.sh` 3. `launch-theme-from-kual.sh` 会先切主题,再委托 `/mnt/us/dashboard/launch-from-kual.sh` 4. `launch-from-kual.sh` 仍会先请求 KUAL 正常退出,并通过 `setsid` 脱离当前会话后启动 `start.sh` 5. 默认 `KUAL_QUIT_GRACE_SECONDS=0`、`KUAL_LAUNCH_DELAY_SECONDS=0`,不再人为停留在原生首页,尽量做到点击后直接进入 calendar overlay 6. `start.sh` 的非调试后台启动也额外加上了 `setsid` ### E. 2026-03-17 新架构:保留原生 UI 栈 为解决“长期显示 calendar,同时仍能切回首页/KUAL”,仓库里新增并默认启用了: - `KEEP_NATIVE_UI_STACK_RUNNING=true` 当前行为是: - `dash.sh` 启动时不再主动停止 `framework / webreader` - `stop.sh` 在该开关打开时,只停止 dashboard 自己,不再重建 `framework / webreader / cvm` - dashboard 作为“覆盖显示层 + RTC suspend 调度”运行,而不是“替代原生 UI 的前台” - 主题切换入口当前只保留在 KUAL;运行态双翻页键菜单与右下角长按默认关闭 - 实机已验证:`calendar -> 主页 -> KUAL -> 回主页` 全链路正常 这条路线已经证明比“启动时停掉 framework/webreader”更符合当前需求。 7. `Dashboard Debug On/Off` 也统一改走同一条 wrapper 启动链 这只能说明“修复方向已经进入代码”,还不能替代真实设备上的交互验收。 更具体地说,截至 `2026-03-17` 的真机实验结果是: 1. wrapper 已经落地 2. `stop.sh` 的实验性快切换已经撤回 3. 当前真正安全的进入方式仍然只有 SSH 前台调试 4. 当前真正安全的退出方式仍然只有保守恢复版 `./stop.sh` 等 SSH 恢复后,再围绕下面三点做实机验证: 1. KUAL wrapper 是否还能触发 `framework` 被 TERM 2. `start.sh` 的后台脱离方式是否足够彻底 3. `stop.sh` 后是否还需要补 `/sbin/start webreader` ## 这轮涉及的关键文件 - [dash/src/dash.sh](/Users/gavin/kindle-dash/dash/src/dash.sh) - [dash/src/start.sh](/Users/gavin/kindle-dash/dash/src/start.sh) - [dash/src/stop.sh](/Users/gavin/kindle-dash/dash/src/stop.sh) - [dash/src/debug-on.sh](/Users/gavin/kindle-dash/dash/src/debug-on.sh) - [dash/src/debug-off.sh](/Users/gavin/kindle-dash/dash/src/debug-off.sh) - [dash/src/local/env.sh](/Users/gavin/kindle-dash/dash/src/local/env.sh) - [dash/src/local/render-clock.sh](/Users/gavin/kindle-dash/dash/src/local/render-clock.sh) - [dash/src/local/render-clock.lua](/Users/gavin/kindle-dash/dash/src/local/render-clock.lua) - [dash/docs/kindle-voyage-5.13.6-dual-ssh-playbook-zh.md](/Users/gavin/kindle-dash/dash/docs/kindle-voyage-5.13.6-dual-ssh-playbook-zh.md) ## 最后结论 本轮后半段的主要问题已经不是 dashboard 页面本身,而是: - dashboard 与 Kindle 原生 `framework/KUAL` 的边界切换不稳定 - `KUAL -> Kindle Dashboard` 这条启动链仍会白屏 - 直接用 shell 强拉 booklet,或手动碰 `blanket`,都会触发前台 `blanket / cvm` 崩溃 因此,当前最重要的不是继续调页面,而是: 1. 保留当前已经可用的 SSH 启动/停止路径 2. 修住 `KUAL -> Kindle Dashboard` 白屏 3. 在不再触发 `blanket / cvm` 崩溃的前提下,把“进入 dashboard”和“退出 dashboard”都收敛成稳定流程