7.5 KiB
7.5 KiB
SBL1 BringUp — статус (2026-09-07)
Цель: выполнить оригинальный SBL1 (RM-1127) в QEMU до баннера SBL1, Start на UART.
Что работает
- Машина
saimaa(qemu/saimaa.c, QEMU 8.2.2 на zern): Cortex-A7×4, DDRLOW/OCIMEM/IMEM/SMEM/RPM/mystrom, UARTDM-стаб, SDHCI+eMMC 8GiB, VFP/NEON вкл (CPACR+NSACR+FPEXC), null-page trap, fault-tolerant векторы. - eMMC-образ с реальной GPT RM-1127 (33 раздела,
tools/mkimage.py). - FFU-разбор (
tools/ffu_parse.py, RKH/MSM/OEM/PlatformID, GPT33). .edp-нарезка ELF (tools/edp_carve.py, 10 образов,fw/sbl/в .gitignore).tools/sbl_patch.py— воспроизводимо генерирует img0_bl..b10.elf из img0.elf.- Стаблеты компенсации pop (
qemu/stublets.S→ 0x08062000): чинят SP, повторы попадают в те же слоты. Слоты вsaimaa_machine_init. - Указательный maze (
0x08062100) + scratch (0x08070000) для struct-цепочек. - Трассировка:
-d in_asm,cpu,guest_errors,int+ GDB (только чтение!continueв batch виснет — использоватьinterrupt+detach).
Найденное
sbl_main(Thumb) =0x802f63e, баннерSBL1, Startзовётся из0x802f6aeчерезbl 0x8016320. Poll IMEM0x08600944!=0x53444247(выходит при 0).- В
.edp-копии вызовыblx immведут в Thumb-код (на HW тоже; QEMU уходит в ARM → патчим вbl, см. sbl_patch.py). Часть вызовов off-by-2/4 (таблица0x8013aa8,bl 0x8018a78→0x8018a7c). - FFU-копия SBL1 — другая сборка тех же исходников (структура та же,
blвместоblx, полные фреймы). Используется как эталон. - PBL-контекст (r4-r12) фабрикуется машиной; таблицы собираются частично.
- Текущий фронтир (b10 + canonical scaffold): ~20 уровней init, падеж
в районе
0x80079xx(див switch по мусорным флагам) — см. свежий трейс.
Запуск
./tools/sbl_patch.py fw/sbl/img0.elf /tmp/p
~/qemu-src/qemu-8.2.2/build/qemu-system-arm \
-M saimaa,sbl1=/tmp/p/img0_b10.elf,sblmain=0x802f63f -m 512 \
-display none -monitor none -serial file:/tmp/uart.log \
-drive file=/tmp/emmc-test.img,if=sd,format=raw
TODO
- Добить баннер (см. свежий in_asm-хвост).
- Заменить стаблеты настоящим PBL (нужны дампы с живого тела!).
- UEFI (img3, EDK2) — отдельный фронт после SBL1.
b18: S7 и цикл delay-helper (2026-09-12)
Механизм зацикливания (b17, доказан Unicorn-harness tools/sbl_uni.py):
- sbl_main → delay-функция
0x8013B78(256-итераций table-walk,bl 0x8017AF4каждую итерацию) → b14 (0x8017AFC: b.w 0x8005B9E) → helper0x8005BB0→ выходldr pc,[sp],#0x14(0x8005BCA) → S3-слот (0x8013BA5, рестарт). - Эпилог delay (
0x8013BAC: pop {r3-r7,pc}) снимает 0x18 без push; каждый S3-рестарт съедает 0x18 живого стека. Маршрут: слоты → fill (STUBV → pop pc = maze) → pristine IMEM (нули → null-jump → hook_null → maze → stale lr) → переполнение IMEM (0x8610008). - Heap SBL (stm в 0x8006684) затирает maze/S6/banner (0, 0x7a, STUBV).
QEMU: dstub-overlay
[0x08006B80,0x08006C50)(read = снапшот ELF+стабы, write = игнор). Uni: deferred-restore guard (MEM_WRITE-хук срабатывает ДО записи, restore надо делать в hook_code!). - Maze-blob:
movs r0,#0; lsr ip,lr,#24; cmp #8; bne hang; bx lr(возврат 0 только для lr из DDRLOW 0x08..., иначе hang). Фикс b18: патч BAC (f8bd0a4a→f3f730b8,b.w S7) + S7-стаблет (52B @ 0x08006C10):cmp r4,#0xff→ iterate (0x8013BA5) или done (restore r4/r5/sl/fp, возврат в sbl_main0x802f681). BAE-путь ([r7]==2) принесён в жертву (r7=0, недостижим). Фронтир b18: sbl_main возвращается, новый код0x801Bxxx(strb [r7,#2]-паттерн, b17-NOP на 0x801B71E), падеж pop'ом пустого стека у верха IMEM — следующий фронт.
b18 parity (QEMU == uni, 2026-09-12)
- QEMU поправлен до паритета: dstub-overlay + vec-maze для Thumb (null-fetch исполняет maze и возвращается) + убран висячий префикс bl (bogus odd store -> alignment fault, DFAR=0x8006B8D).
- QEMU b18 доходит до того же фронтира, что uni b18 (38961 инстр.):
0x801Bxxx, r1=0x80522A4, r2/r3=STUBV, lr=0x801B73F, sp марширует к верху IMEM. Смерти чуть различаются по таймингу (uni: read 0x8610000; QEMU: null-jump → maze-hang c lr-top 0x80), регион тот же. - Следующий фронт (оба): лабиринт
0x801B6xx(логгер, r7=0/r4=0, pop пустого стека). Кандидаты: S8-стаблет, таблица логгера.
b21-b23: логгер, S9, S10, rollback (2026-09-12)
- Логгер
0x8034810= голыйpop.w 0x28без push (жрал стек) → S8: вход →bx lr(b21). Возврат игнорируется (callers ставят r0=0). - Лабиринт
0x801B6A0: счётчик[r4]+++pop.wна пустых фреймах (r4/r7=STUBV из fill) → S9 (b22):[sp+0x14]ненулевой → исходный pop; ноль → restore r0/r4/r5/sl/fp + reset sp=0x085FFF00 + прыжок в sbl_main0x802f69dчерез ip (без литералов). - Rollback
boot_rollback_version.c:580(query всегда0x302E) → NOP NOP (b22, возврат игнорируется). Query зовёт*table[0x080528D0](нули) → фабрикация: poke STUBV (maze вернёт 0 = версии OK) (b23). - Rollback выходил боком в helper-mid (
pop{r4,pc}без push) → S10 (b23):movw/movt ip + bx ipв sbl_main0x802f6a3. - b23: 2M инстр. без падений (sp здоров), sbl_main идёт дальше
(
0x80164C4-subtree → прыжок в OCIMEM-нули0x222F84— фронт PBL-данных). QEMU-паритет: R15=0x223000, sp=0x85FFF00, lr=0x80164CB — там же.
b24: world-switch stub, clock S11 (2026-09-12)
- Диспетчер (
0x80164C4-subtree) зовёт ARM jump-table0x8007158(ldr pc), та — в OCIMEM-трамплин world-switch0x221EF8(ARM: save regs,cps MON,mrc,ldr sp/pcиз PBL-таблиц[0x221F6C]=0x223620/[0x221F70]=0x223930→ вызов TZ; TZ не загружен). Вход получается в Thumb → b24-стаб (4Bmovs r0,#0; bx lr): возврат 0 в диспетчер (TZ deferred). Перезаписывает голову ARM'а (восстановимо из ELF). - Дальше: clock-fn
0x800E960(udiv-подсчёты) с голым выходомpop{r4,pc}(без push, tail-chain через NOP-идиому) → S11 (b24): вход →bx lr(lr = брошенный-но-валидный0x80076CD).