mirror of
https://github.com/MCKero6423/uv-k5-v3-emulator.git
synced 2026-10-05 20:47:28 +00:00
Round 61: the overlay memset runs from a chain 0x080175fe -> 0x08016ff0 -> memset, a hundred times a second
Reading the stack at the watchpoint hits gives the same chain every time: PC=0x0801ae7a (inside memset, entry 0x0801ae70), SP=0x20003c50, with return addresses 0x080047ca and 0x080175fe. So 0x080175fe calls the routine at 0x08016ff0, which calls memset(0x20000280, 0, 0x1000) from 0x0801701a, about a hundred times a second. Caveat worth stating: the sources quoted in recent rounds -- app_overlay.c, py25q16.c, radio.c -- came from armel/uv-k1-k5v3-firmware-custom's main branch while the running image is f4hwn's build. They need not be the same lineage, so claims like 'this routine is APP_LaunchOverlay' are inferences from those files rather than facts about this image. What is measured and source-independent: a routine at 0x08016ff0 is entered about a hundred times a second and each time zeroes the whole 4 KiB overlay, while the code is read into it exactly once -- so nothing the loader writes can survive, which is why a 24-byte app passes its CRC check and a 2568-byte one does not.
This commit is contained in:
1 parent
028eaef057
commit
244c51c2e1
2 files changed
+48
No files matched your search
@@ -2405,3 +2405,27 @@ a second while the code is loaded once, so nothing the loader writes can survive
|
||||
The next measurement needs no disassembler: at the 1200 hits the stack pointer is 0x20003c50, so reading the
|
||||
words above it gives the whole return-address chain and therefore who calls the routine that calls memset. One
|
||||
run of that names the retry loop.
|
||||
|
||||
**Round 61: the call chain is 0x080175fe -> 0x08016ff0 -> 0x0801701a -> memset, and it runs about a hundred times a second.**
|
||||
|
||||
Reading the stack words at the watchpoint hits -- stack pointer 0x20003c50 -- gives the same chain every time:
|
||||
|
||||
PC=0x0801ae7a (inside memset, entry 0x0801ae70) SP=0x20003c50
|
||||
return addresses on the stack: 0x080047ca 0x080175fe
|
||||
|
||||
So 0x080175fe calls the routine whose prologue is at 0x08016ff0, which calls memset(0x20000280, 0, 0x1000) from
|
||||
0x0801701a. That is the whole path, and it is taken about a hundred times a second.
|
||||
|
||||
A caveat that matters, and that I should have stated earlier: the sources I have been quoting -- app_overlay.c,
|
||||
py25q16.c, radio.c -- were fetched from armel/uv-k1-k5v3-firmware-custom's main branch, while the image running
|
||||
here is f4hwn's build. They need not be the same lineage, so "this routine is APP_LaunchOverlay" and "that
|
||||
memset is the launcher's own" are inferences from those files, not facts about this image. Nothing in the last
|
||||
few rounds that rests on a fetched source should be treated as proven.
|
||||
|
||||
What is measured, and independent of any source: a routine at 0x08016ff0 is entered about a hundred times a
|
||||
second and each time zeroes the whole 4 KiB overlay through memset, while the code itself is read into that
|
||||
overlay exactly once. Whatever the routine is called, nothing the loader writes can survive it, which is why a
|
||||
24-byte app passes its CRC check and a 2568-byte one does not.
|
||||
|
||||
Next: identify 0x080175fe and 0x080047ca against the image itself rather than against a fetched file -- for
|
||||
instance by looking at what each calls and returns -- or fetch the sources for the exact build being run.
|
||||
@@ -2099,3 +2099,27 @@ DMA tx=4 rx=3 count=2568 tx_addr=0x20001338 rx_addr=0x20000280 tx_inc=0 rx_inc=1
|
||||
|
||||
**下一个测量不需要反汇编器** ✓:那 1200 次命中时 `SP = 0x20003c50` ✓,所以**把它上面的字读出来,就得到整条返回地址链** ✓ ——
|
||||
**也就得到「谁在调用那个调用 `memset` 的例程」** ✓。**跑一次就能给那个重试循环定名** ✓。
|
||||
|
||||
**第 61 轮:调用链是 `0x080175fe` → `0x08016ff0` → `0x0801701a` → `memset`,而它每秒执行约一百次。**
|
||||
|
||||
在监视点命中处读栈(`SP = 0x20003c50` ✓),每一次得到的都是同一条链:
|
||||
|
||||
```
|
||||
PC=0x0801ae7a(`memset` 内部,入口 0x0801ae70) SP=0x20003c50
|
||||
栈上的返回地址: 0x080047ca 0x080175fe
|
||||
```
|
||||
|
||||
**所以是 `0x080175fe` 调用序言在 `0x08016ff0` 的例程,而它在 `0x0801701a` 处调用 `memset(0x20000280, 0, 0x1000)`** ✓。
|
||||
**这就是整条路径,而它每秒被走约一百次。**
|
||||
|
||||
**有一条要紧的前提,我本该更早说明** ✗:**我一直在引用的那些源码 —— `app_overlay.c`、`py25q16.c`、`radio.c` —— 是从
|
||||
`armel/uv-k1-k5v3-firmware-custom` 的 main 分支取的 ✓,而这里跑的镜像是 f4hwn 的构建 ✓。两者未必同源** ✗✓。
|
||||
所以「这个例程就是 `APP_LaunchOverlay`」「那次 `memset` 就是启动器自己的」都只是**从那些文件推出的** ✓,
|
||||
**而不是关于这份镜像的事实** ✓。**近几轮里任何依赖「取来的源码」的结论,都不该被当作已证。**
|
||||
|
||||
**而有一条测量是独立于任何源码的** ✓:**`0x08016ff0` 那个例程每秒被进入约一百次 ✓,每次都通过 `memset` 把那整片 4 KiB 覆盖区清零 ✓**,
|
||||
**而代码本身只被读进那片覆盖区一次** ✓。**无论那个例程叫什么,加载器写进去的东西都活不过它** ✓ ——
|
||||
**这正是「24 字节的应用能过 CRC、2568 字节的过不了」的原因** ✓。
|
||||
|
||||
**下一步**:**对着镜像本身、而不是对着取来的文件,去认 `0x080175fe` 与 `0x080047ca`** ✓ ——
|
||||
比如看它们各自调用与返回了什么 ✓ —— **或者去取「正在跑的那个构建」的源码** ✓。
|
||||
Reference in new issue
Block a user