diff --git a/AGENTS.md b/AGENTS.md
index 177b437..2b8798a 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -113,12 +113,14 @@ what it reads.
tools/where.sh # where execution is
tools/gpiob_dump.sh # GPIOB registers
python3 tools/key.py MENU # inject a keypress
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # this firmware's addresses
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
-Screenshot addresses move between firmware builds. Get the current ones with:
-
- arm-none-eabi-nm firmware.elf | grep -E 'gFrameBuffer|gStatusLine'
+Screenshot addresses move between firmware builds, and `screenshot.py` reads guest RAM, so
+it needs them. `tools/uvk5_buffers.py` finds them in the running firmware by matching the
+display controller's memory against SRAM -- the images built here are program-header-only
+ELFs with no symbol table, so `nm` has nothing to read for them (a fully linked ELF does).
Rebuild after editing the machine:
@@ -133,8 +135,7 @@ session:
There is also a browser UI, which is usually the quickest way to poke at the
firmware by hand:
- python3 tools/webui.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C # then open http://127.0.0.1:8080/
+ python3 tools/webui.py # no addresses: the page draws the panel's memory
Two things about it that matter when working on this repo:
@@ -785,8 +786,9 @@ checks can be pointed at whatever tree you have.
The flag check earned its own lesson. Its first version matched only to the end of the
line, so on a wrapped command like
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # this firmware's addresses
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
it saw `--frame-addr` and nothing else -- 4 of 9 flags, and it reported a clean run.
**A check that silently covers a quarter of what it claims is worse than no check**,
diff --git a/AGENTS.zh-CN.md b/AGENTS.zh-CN.md
index 524f368..b62c6c5 100644
--- a/AGENTS.zh-CN.md
+++ b/AGENTS.zh-CN.md
@@ -95,12 +95,13 @@ bootloader 区域,所以应用在它之后。`armv7m_load_kernel()` 之所以
tools/where.sh # 执行到哪了
tools/gpiob_dump.sh # GPIOB 寄存器
python3 tools/key.py MENU # 注入一次按键
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # 这份固件把它们放在哪
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
-截图用的地址在不同固件构建之间会变。这样拿到当前值:
-
- arm-none-eabi-nm firmware.elf | grep -E 'gFrameBuffer|gStatusLine'
+截图用的地址在不同固件构建之间会变,而 `screenshot.py` 读的是 guest RAM,所以需要它们。
+`tools/uvk5_buffers.py` 会把控制器显存和 SRAM 做匹配、从正在运行的固件里找出来 —— 这里构建出来的
+镜像是**只有程序头的最小 ELF、没有符号表**,所以 `nm` 对它们无字可读(完整链接的 ELF 才有)。
改完机器模型后重新构建:
@@ -113,8 +114,7 @@ bootloader 区域,所以应用在它之后。`armv7m_load_kernel()` 之所以
还有一个浏览器界面,通常是手动折腾固件最快的方式:
- python3 tools/webui.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C # 然后打开 http://127.0.0.1:8080/
+ python3 tools/webui.py # 不需要地址:页面画的是面板显存
关于它,有两点在这个仓库里干活时需要知道:
@@ -645,8 +645,9 @@ GCC 能看到全部调用者。如果一个模型的输出神秘地不起作用
参数检查本身也留下了一个教训。它的第一版只匹配到行尾,所以对一条这样换行的命令
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # 这份固件把它们放在哪
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
它只看到了 `--frame-addr`,别的都没看到 —— 9 个参数里查了 4 个,然后**报告一切干净**。
**一个静默地只覆盖了自己所声称范围四分之一的检查,比没有检查更糟**,
diff --git a/README.md b/README.md
index 79bf31c..0eda6d4 100644
--- a/README.md
+++ b/README.md
@@ -186,9 +186,9 @@ Five minutes from a checkout to a running radio on a web page.
`--frame-addr` and `--status-addr` are optional, and normally omitted. The page draws the
**display controller's own memory**, which is the screen for every firmware and needs no
-addresses at all; those two only serve the guest-RAM fallback, and `tools/uvk5_buffers.py`
-finds them in whatever firmware is running (`--frame-addr` on the command line skips the
-search). Nothing in this repository holds a build's addresses.
+addresses at all; those two only serve the guest-RAM fallback, and the addresses are read
+out of whatever firmware is running by `tools/uvk5_buffers.py`. Giving one on the command
+line skips that search. Nothing in this repository holds a build's addresses.
Drop any `.bin` on the page to boot it. The page's **Firmware slots** table reads and
writes the multi-system firmware's four slots in the flash image, and **Multiboot**
@@ -284,8 +284,9 @@ stays ignored: it is a build artifact that gets written to.
tools/run.sh # starts the machine
tools/where.sh # where the firmware is executing
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # where this firmware keeps them
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
python3 tools/key.py MENU # inject a keypress
tools/gpiob_dump.sh # GPIOB registers
@@ -304,8 +305,7 @@ between builds. Find them with:
driven from a browser instead of `key.py` plus `screenshot.py`.
tools/run.sh # emulator first
- python3 tools/webui.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C # then the server
+ python3 tools/webui.py # no addresses: it draws the panel
Open . The keypad is laid out like the radio, with the
side keys alongside. Arrow keys, Enter (MENU), Esc (EXIT) and the digits are
diff --git a/README.zh-CN.md b/README.zh-CN.md
index bfc8f91..10d5741 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -163,9 +163,9 @@ uvk5_elf.sh 探针脚本从哪里找固件(环境变量,然后本
--elf assets/firmware/f4hwn.fieldops.v6.0.0.bin # 然后打开 http://127.0.0.1:8080/
`--frame-addr` 与 `--status-addr` 都是可选的,通常不传。页面画的是**显示控制器自己的显存** ——
-对任何固件那就是屏幕,不需要任何地址;这两个参数只服务 guest RAM 回落路径,而
-`tools/uvk5_buffers.py` 会从**正在运行的那份固件**里把它们找出来(命令行给了 `--frame-addr`
-就跳过搜索)。仓库里不保存任何一份构建的地址。
+对任何固件那就是屏幕,不需要任何地址;这两个参数只服务 guest RAM 回落路径,而地址是由
+`tools/uvk5_buffers.py` 从**正在运行的那份固件**里读出来的。自己在命令行给一个,就跳过这次搜索。
+仓库里不保存任何一份构建的地址。
把任意 `.bin` 拖到页面上即可启动。页面上的 **Firmware slots** 表可以读写 flash 镜像里
多系统固件的四个槽位,**Multiboot** 会按住 MENU 重启以进入多系统菜单——前提是那份构建
@@ -256,8 +256,9 @@ uvk5_elf.sh 探针脚本从哪里找固件(环境变量,然后本
tools/run.sh # 启动机器
tools/where.sh # 固件当前执行到哪里
- python3 tools/screenshot.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C --port 1234 --out screen.png
+ python3 tools/uvk5_buffers.py --qmp 127.0.0.1:4444 # 这份固件把它们放在哪
+ python3 tools/screenshot.py --frame-addr 0x... --status-addr 0x... \
+ --port 1234 --out screen.png
python3 tools/key.py MENU # 注入一次按键
tools/gpiob_dump.sh # GPIOB 寄存器
@@ -274,8 +275,7 @@ uvk5_elf.sh 探针脚本从哪里找固件(环境变量,然后本
不用反复敲 `key.py` 加 `screenshot.py`。
tools/run.sh # 先起模拟器
- python3 tools/webui.py --frame-addr 0x200013DC \
- --status-addr 0x2000175C # 再起服务
+ python3 tools/webui.py # 不需要地址:它画的是面板显存
打开 。键盘按电台的实际布局排列,侧键在旁边。方向键、
回车(MENU)、Esc(EXIT)和数字键都绑定到了对应的物理按键。