From 7a77e33eda6e42007b9ef7f4b4eb0af40589112f Mon Sep 17 00:00:00 2001 From: lumia-emu Date: Sun, 13 Sep 2026 12:12:51 +0000 Subject: [PATCH] b27: poll re-init skip + bits pref-set --- docs/sbl-bringup.md | 5 +++ qemu/run-sbl.sh | 2 +- qemu/saimaa.c | 5 ++- tools/sbl_patch.py | 89 +++++++++++++++++++++++++++++++++++++++++++++ tools/sbl_uni.py | 8 ++-- 5 files changed, 102 insertions(+), 7 deletions(-) diff --git a/docs/sbl-bringup.md b/docs/sbl-bringup.md index b064cf2..a4c362f 100644 --- a/docs/sbl-bringup.md +++ b/docs/sbl-bringup.md @@ -120,3 +120,8 @@ в rodata `[0x804B800,0x8058000)` (wild-указатели скипаются), затем pop-return (без leak'а, возврат игнорируется). Логгер `0x8034810` (`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). diff --git a/qemu/run-sbl.sh b/qemu/run-sbl.sh index 54cceab..90d5e8f 100755 --- a/qemu/run-sbl.sh +++ b/qemu/run-sbl.sh @@ -5,7 +5,7 @@ set -e cd "$(dirname "$0")/.." QEMU=~/qemu-src/qemu-8.2.2/build/qemu-system-arm -B=${1:-b24} +B=${1:-b27} IMG=fw/img/emmc-real.img 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" diff --git a/qemu/saimaa.c b/qemu/saimaa.c index edff0cc..057d69d 100644 --- a/qemu/saimaa.c +++ b/qemu/saimaa.c @@ -719,9 +719,10 @@ static void saimaa_machine_init(MachineState *machine) uint32_t v = 0x08006B8D; 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); } /* PBL world-switch Thumb-stub (b24, 4B @0x00221EF8): diff --git a/tools/sbl_patch.py b/tools/sbl_patch.py index 8701121..e354abf 100644 --- a/tools/sbl_patch.py +++ b/tools/sbl_patch.py @@ -1126,6 +1126,95 @@ def main(): 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') + diff --git a/tools/sbl_uni.py b/tools/sbl_uni.py index 7d15946..202c605 100644 --- a/tools/sbl_uni.py +++ b/tools/sbl_uni.py @@ -375,10 +375,10 @@ def main(): # PBL version-table fabrication (b23): [0x080528D0] = STUBV so the # rollback query's blx calls maze (returns 0 = versions OK). W32(0x080528D0, STUBV) - # HW-ready bit fabrication (b25): [0x073A100] bit2 = peripheral - # status done-bit (SBL only reads it, never writes; HW would set it). - # Poll is lsls#29+bpl (checks bit2, NOT bit31!). - W32(0x073A100, 0x00000004) + # HW-ready bit fabrication (b25): [0x073A100] bits 0,1,2 = peripheral + # status done-bits (poll#1 checks bit2 (lsls#29), poll#2 bit1 (lsls#30), + # post-poll gate bit0 (lsls#31)). SBL only reads it, never writes. + W32(0x073A100, 0x00000007) # PBL world-switch Thumb-stub (b24): the ARM trampoline at 0x221EF8 # 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