diff --git a/AGENTS.md b/AGENTS.md index ed321cb..8d5bd6d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -749,6 +749,28 @@ with the panel blank or showing only its boot screen, and keys then do nothing - rounds mistook for the app's failure. And never hand-start QEMU for this: the hand-started instances came up without a picture, while the page's own instance draws. +**The overlay app starts, runs, and dies the moment it calls a firmware service that reads the external flash.** + +Measured on the page's own emulator with its probes on (UVK5_PC_PROBE / UVK5_FLASH_PROBE inherited through its own +launcher, so the instance being measured is the one that draws). Three apps, same row, same keys: + +* **Spin, 16 bytes, calls nothing**: after MENU it is at 0x20000286 in 42 of 383 PC samples, i.e. it loops in the + overlay forever. The loader works. +* **Minesweeper, 2408 bytes**: the flash probe shows exactly one big read, 0x109000 len 2408, whose first bytes are + the blob's own, so the code is loaded; the PC probe catches a single sample inside the overlay before the app is + gone. It lives well under 100 ms and dies. +* **Phases, 372 bytes**, which draws a bar straight into the framebuffer between calls so the screen reports how far + it got: the bars for framebuffer-only and for led are on screen, and the bar after delay_ms never appears. + +The overlay is the PY25Q16 sector cache -- app_overlay.h says so itself (it copies the code into the 4 KiB overlay, +the PY25Q16 sector cache, shared VMA with the multiboot RAM stub). So the picture is: while the app runs, a service +reads the external flash (the font table lives at 0x1E0000 there), the sector lands on top of the app, and the app +executes flash data. Real hardware cannot behave that way -- upstream's own apps call print_tiny -- so the firmware +must gate the sector cache while an app is loaded, and **that gate is what the model is missing**. + +Next: find the gate in the firmware's flash driver (a memory flag, a register, a GPIO) and check what the model +answers for it. This is the first time the failure has a name and a reproducible three-app comparison behind it. + ## The keypad: two real bugs, both fixed The old note here said "keys reach the firmware but the UI does not react" and diff --git a/AGENTS.zh-CN.md b/AGENTS.zh-CN.md index cd55d65..e812c9e 100644 --- a/AGENTS.zh-CN.md +++ b/AGENTS.zh-CN.md @@ -606,6 +606,27 @@ app 区被读过 —— 而多系统菜单读的是**固件槽**,不是应用 (image_crc32 是 0x9d27c3db 而不是 0x4d87ce48)的工作副本起来时面板是空的、或只显示启动画面,那时按键也不响应 —— 前面好几轮把这当成了"应用失败"。另外**永远不要手工启动 QEMU** 来测这个:手工起的实例没有画面,而页面自己的实例是画的。 +**叠加应用能启动、能跑,而一旦调用 <<会读外部 flash 的固件服务>> 就当场死掉。** + +在页面自己的模拟器上、打开模型探针测得(UVK5_PC_PROBE / UVK5_FLASH_PROBE 通过它自己的启动器继承,因此被测量的 +正是那个会画画的实例)。三个应用、同一行、同一串按键: + +* **Spin,16 字节,什么都不调用**:MENU 之后 383 个 PC 样本里有 **42 个**停在 `0x20000286` —— 它就在叠加区里 + 无限循环。**加载器完全正常。** +* **扫雷,2408 字节**:flash 探针里只有一次大读取 0x109000 len=2408,首字节就是块自己的 —— 代码确实被加载了; + 而 PC 探针只捕到**一个**落在叠加区的样本,随后应用就没了。它活了**远不到 100 ms**。 +* **Phases,372 字节**:每次调用之间直接往帧缓冲画一条横杠,于是**屏幕自己报告走到了哪一步** —— 只写帧缓冲与 led + 两条横杠都在屏上,而 **delay_ms 之后那条从未出现**。(blit_full 与 led 能活过;一旦让出 CPU 去走固件自己的 + 服务,就死。) + +叠加区**就是** PY25Q16 的扇区缓存 —— app_overlay.h 自己写着:它把代码拷进 4 KiB 叠加区(也就是 PY25Q16 扇区 +缓存,与多系统 RAM stub 共用同一 VMA)。所以图景是:应用运行期间,某个服务去读外部 flash(字库表就在 0x1E0000), +整个扇区就落在应用头上,应用开始执行 flash 数据。真机上不可能这样 —— 上游自己的应用就调用 print_tiny —— 所以固件 +必然在**应用已加载时对扇区缓存加了门**,而**模型缺的正是这道门**。 + +下一步:在固件的 flash 驱动里找到这道门(一个内存标志、一个寄存器、还是一根 GPIO),再看模型在被问到时答的是什么。 +这是第一次,这个故障有了名字、也有了三个应用的可复现对照。 + ## 键盘:两个真 bug,都已修复 这里原来的笔记写的是"按键到达了固件但界面不反应",并且归咎于机器模型。结果发现有**两个