From afc151ce0c875e3accac8f6ccdadacdd7e11a602 Mon Sep 17 00:00:00 2001 From: SashegDev Date: Fri, 11 Sep 2026 06:40:20 +0000 Subject: [PATCH] sbl b16: banner blx redirected to print stublet 0x8062150 --- qemu/banner.S | 18 ++++++++++++++++++ qemu/saimaa.c | 21 +++++++++++++++++++++ tools/sbl_patch.py | 27 +++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 qemu/banner.S diff --git a/qemu/banner.S b/qemu/banner.S new file mode 100644 index 0000000..ba49f24 --- /dev/null +++ b/qemu/banner.S @@ -0,0 +1,18 @@ + .syntax unified + .cpu cortex-a7 + .thumb + @ Banner stub for SBL1 logger call at 0x802f690 (blx r3 patched to bl here). + @ r0 = string. Print raw bytes via UARTDM until NUL (cap 256), return 0. + .text + .global banner_stub +banner_stub: + movw r3, #0xf000 + movt r3, #0x78a +bn_loop: + ldrb r1, [r0], #1 + cbz r1, bn_done + str r1, [r3, #0x70] + b bn_loop +bn_done: + movs r0, #0 + bx lr diff --git a/qemu/saimaa.c b/qemu/saimaa.c index ffb25db..767c295 100644 --- a/qemu/saimaa.c +++ b/qemu/saimaa.c @@ -439,6 +439,27 @@ static void saimaa_machine_init(MachineState *machine) cpu_physical_memory_write(0x08062140 + k, &word, 4); } } + /* Banner stub at 0x08062150: print r0 string via UARTDM + * (b16 redirects 0x802f690 blx here). Built from qemu/banner.S */ + { + static const uint8_t bn[] = { + 0x4f, 0xf2, 0x00, 0x03, /* movw r3,#0xf000 */ + 0xc0, 0xf2, 0x8a, 0x73, /* movt r3,#0x78a */ + 0x10, 0xf8, 0x01, 0x1b, /* ldrb r1,[r0],#1 */ + 0x09, 0xb1, /* cbz r1,done */ + 0x19, 0x67, /* str r1,[r3,#0x70] */ + 0xfa, 0xe7, /* b loop */ + 0x00, 0x20, /* movs r0,#0 */ + 0x70, 0x47, /* bx lr */ + }; + size_t k; + for (k = 0; k < sizeof(bn); k += 4) { + uint32_t word = 0; + size_t n = sizeof(bn) - k < 4 ? sizeof(bn) - k : 4; + __builtin_memcpy(&word, &bn[k], n); + cpu_physical_memory_write(0x08062150 + k, &word, 4); + } + } /* stack zone defaults to plain-stub addr: every register * popped from untouched stack becomes callable (returns 0). */ { diff --git a/tools/sbl_patch.py b/tools/sbl_patch.py index 7ca80c3..87430b2 100644 --- a/tools/sbl_patch.py +++ b/tools/sbl_patch.py @@ -159,6 +159,33 @@ def main(): assert d[o:o + 2].hex() == 'b888', (hex(0x8013BA6), hx(d, 0x8013BA6, 2)) d[o:o + 2] = bytes.fromhex('ff20') save(d, 'img0_b15.elf') + # b16 = b15 + banner call redirect (0x802f690 blx r3 -> bl banner stub + # at 0x08062150; table[0] is garbage 0x690ce0ee). Stub prints r0 string + # via UARTDM, returns 0 -> falls into cbz path (banner done). + 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'), + (0x8006684, '01f807bd', '46c046c0'), + (0x8017AFC, 'bde8fc87', '4af020bb'), + (0x802F690, '4798e7fe', '32f05ebd'), + ]: + assert hx(d, va) == exp, (hex(va), hx(d, va)) + set4(d, va, new) + 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') + save(d, 'img0_b16.elf') # b14 = b13 + redirect S6 pop (0x8017afc ldmia.w sp!,{r2-r9,sl,pc}) # to S6 stublet at 0x08062140 (pc slot clobbered to 0 at runtime) d = bytearray(base)