b27: poll re-init skip + bits pref-set

This commit is contained in:
SashegDev
2026-09-13 12:12:51 +00:00
parent 8b1eaeba18
commit 9cd903c34d
5 changed files with 102 additions and 7 deletions
+5
View File
@@ -120,3 +120,8 @@
в rodata `[0x804B800,0x8058000)` (wild-указатели скипаются), затем в rodata `[0x804B800,0x8058000)` (wild-указатели скипаются), затем
pop-return (без leak'а, возврат игнорируется). Логгер `0x8034810` pop-return (без leak'а, возврат игнорируется). Логгер `0x8034810`
(`pop.w` 4B) → `b.w S17`. Видимость прогресса вместо счёта инстр. (`pop.w` 4B) → `b.w S17`. Видимость прогресса вместо счёта инстр.
## b27: poll re-init skip (2026-09-13)
- Poll-fn `0x8007748`: `cbz r6` (r6=2 константа caller'а, никогда 0) →
вечный re-init (`movs r4,#0`, table loop) вместо poll#2-direct.
Патч 2B→2B в `b`. Биты 0,1,2 `[0x73A100]` pref-set (scaffold).
+1 -1
View File
@@ -5,7 +5,7 @@
set -e set -e
cd "$(dirname "$0")/.." cd "$(dirname "$0")/.."
QEMU=~/qemu-src/qemu-8.2.2/build/qemu-system-arm QEMU=~/qemu-src/qemu-8.2.2/build/qemu-system-arm
B=${1:-b24} B=${1:-b27}
IMG=fw/img/emmc-real.img IMG=fw/img/emmc-real.img
if [ ! -f "$IMG" ]; then if [ ! -f "$IMG" ]; then
echo "no $IMG — сначала: python3 tools/ffu_extract.py fw/dl/RM1127_059X5R5_orig.ffu --emmc-user fw/img/user-real.bin" echo "no $IMG — сначала: python3 tools/ffu_extract.py fw/dl/RM1127_059X5R5_orig.ffu --emmc-user fw/img/user-real.bin"
+3 -2
View File
@@ -719,9 +719,10 @@ static void saimaa_machine_init(MachineState *machine)
uint32_t v = 0x08006B8D; uint32_t v = 0x08006B8D;
cpu_physical_memory_write(0x080528D0, &v, 4); cpu_physical_memory_write(0x080528D0, &v, 4);
} }
/* HW-ready bit (b25): [0x073A100] bit2 (SBL read-only poll). */ /* HW-ready bits (b25/b26): [0x073A100] bits 0,1,2 (SBL
* read-only polls: bit2 poll#1, bit1 poll#2, bit0 gate). */
{ {
uint32_t v = 0x00000004; uint32_t v = 0x00000007;
cpu_physical_memory_write(0x073A100, &v, 4); cpu_physical_memory_write(0x073A100, &v, 4);
} }
/* PBL world-switch Thumb-stub (b24, 4B @0x00221EF8): /* PBL world-switch Thumb-stub (b24, 4B @0x00221EF8):
+89
View File
@@ -1126,6 +1126,95 @@ def main():
save(d, 'img0_b26.elf') save(d, 'img0_b26.elf')
# b27 = b26 + poll re-init skip (0x8007748 cbz r6 -> b):
# r6 (table mode, caller-passed constant 2) never 0, so the poll-fn
# re-inits (movs r4,#0) and re-runs its table loop forever instead of
# proceeding to poll#2-direct + epilogue. Force direct (2B->2B).
# Bits 0,1,2 of [0x73A100] pre-set (scaffold), so polls exit.
d = bytearray(base)
for va, (a, b) in BLX2BL.items():
set4(d, va, b)
for va, exp, new in [
(0x802F664, 'e4f77efc', 'c046c046'),
(0x802F672, 'e6f7bbfa', 'c046c046'),
(0x802F678, 'e9f7fef9', 'c046c046'),
(0x801B71E, '9847fee7', 'c046c046'),
(0x8008396, 'fef780f9', 'c046c046'),
(0x8016184, 'fdf790fc', 'c046c046'),
(0x801B76C, '280b0508', '00000708'),
(0x8017AFC, 'bde8fc87', 'eef74fb8'),
(0x802F690, '9847fee7', 'c046c046'),
(0x801671C, '9847fee7', 'c046c046'),
(0x8013BAC, 'f8bd0a4a', 'f3f730b8'),
(0x801B6BE, 'bde8f081', 'ebf7c3ba'),
(0x8016720, '10bd0000', 'f0f7b2ba'),
(0x8034810, 'bde8fc87', 'd2f76eba'),
]:
assert hx(d, va) == exp, (hex(va), hx(d, va))
set4(d, va, new)
# Poll re-init skip (b27): cbz r6 (2B 96b1) -> b (2B 14e0).
o = off(0x8007748)
assert d[o:o + 2].hex() == '96b1', hx(d, 0x8007748, 2)
d[o:o + 2] = bytes.fromhex('14e0')
# Full bl idiom at 0x8006682 (bl + pop, 6B) -> NOPs (see b18).
o = off(0x8006682)
assert d[o:o + 6].hex() == '00f001f807bd', hx(d, 0x8006682, 6)
d[o:o + 6] = bytes.fromhex('c046c046c046')
o = off(0x8013AA8)
assert d[o:o + 4].hex() == '07f026be', hx(d, 0x8013AA8)
d[o:o + 4] = bytes.fromhex('c046c046')
o = off(0x8013BA6)
assert d[o:o + 2].hex() == 'b888', (hex(0x8013BA6), hx(d, 0x8013BA6, 2))
d[o:o + 2] = bytes.fromhex('ff20')
# Helper-pop S16 chain (see b25).
o = off(0x8007B66)
assert d[o:o + 2].hex() == '10bd', hx(d, 0x8007B66, 2)
d[o:o + 2] = bytes.fromhex('6047')
# Clock S11 (see b24).
o = off(0x800E988)
assert d[o:o + 2].hex() == '10bd', hx(d, 0x800E988, 2)
d[o:o + 2] = bytes.fromhex('7047')
save(d, 'img0_b27.elf')
+4 -4
View File
@@ -375,10 +375,10 @@ def main():
# PBL version-table fabrication (b23): [0x080528D0] = STUBV so the # PBL version-table fabrication (b23): [0x080528D0] = STUBV so the
# rollback query's blx calls maze (returns 0 = versions OK). # rollback query's blx calls maze (returns 0 = versions OK).
W32(0x080528D0, STUBV) W32(0x080528D0, STUBV)
# HW-ready bit fabrication (b25): [0x073A100] bit2 = peripheral # HW-ready bit fabrication (b25): [0x073A100] bits 0,1,2 = peripheral
# status done-bit (SBL only reads it, never writes; HW would set it). # status done-bits (poll#1 checks bit2 (lsls#29), poll#2 bit1 (lsls#30),
# Poll is lsls#29+bpl (checks bit2, NOT bit31!). # post-poll gate bit0 (lsls#31)). SBL only reads it, never writes.
W32(0x073A100, 0x00000004) W32(0x073A100, 0x00000007)
# PBL world-switch Thumb-stub (b24): the ARM trampoline at 0x221EF8 # PBL world-switch Thumb-stub (b24): the ARM trampoline at 0x221EF8
# is entered in Thumb (mode confusion at dispatch); real ARM would # is entered in Thumb (mode confusion at dispatch); real ARM would
# save regs/CPS to MON and call TZ (not loaded yet). Stub returns 0 # save regs/CPS to MON and call TZ (not loaded yet). Stub returns 0