b27: poll re-init skip + bits pref-set
This commit is contained in:
@@ -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).
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+3
-2
@@ -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):
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user