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)和数字键都绑定到了对应的物理按键。