Round 37: stub-free entry shim; U-BOOT.md handoff doc; payload cc014efa
The diagnostic wrapper phase (magenta fill, 3-blink train, 5 s hold) is removed; the shim keeps only the load-bearing display revival (OVL_EN, OVL0_2L_EN, backlight GPIOs) and the patched branch to U-Boot. U-BOOT.md documents the boot chain, payload layout constants, build/flash/verify commands, recovery and the U-Boot tree state. U-Boot was rebuilt with the user's hand-tuned .config (16x32 font, CONFIG_CHROMEOS) without re-running the defconfig.
This commit is contained in:
+33
@@ -1429,3 +1429,36 @@ load-bearing options (USB/PHY/CONSOLE/PREBOOT), not just the new one.
|
||||
| USB lines present but no keys | keyboard enumeration issue — transcribe the `Bus ...` line |
|
||||
|
||||
Awaiting user reboot report.
|
||||
|
||||
## Round 37 — Round 36 VERIFIED (landscape + keyboard work); stub-free payload
|
||||
|
||||
User confirmed Round 36 fully works (landscape upright, keyboard
|
||||
functional). User took over the config: `.config` hand-tuned with
|
||||
VIDEO_FONT_16X32 (bigger console font), CONFIG_CHROMEOS=y,
|
||||
VIDEO_ANSI off — the defconfig re-run must therefore NOT be executed
|
||||
blindly anymore (documented in U-BOOT.md).
|
||||
|
||||
### Stub removal (payload `cc014efa…`)
|
||||
|
||||
The entry shim kept only the load-bearing part: OVL_EN/OVL0_2L_EN=1,
|
||||
backlight GPIOs 43/176 on, patched branch to U-Boot. Removed the
|
||||
diagnostic phase (magenta fill, 3-blink train, 5 s hold, delay
|
||||
subroutine). The shim itself cannot be removed: depthcharge jumps to
|
||||
payload+0x40 and U-Boot's PIE fixup needs runtime _start 4K-aligned
|
||||
so U-Boot stays at image offset 0x1000. The build script's single
|
||||
`b .` search-and-patch still applies (the patched branch is now the
|
||||
only instruction after the revival writes).
|
||||
|
||||
### Verification
|
||||
|
||||
U-Boot built with the user's .config untouched; `_start` still
|
||||
0x4C001000 == __image_copy_start; wrapper now 64 bytes (0x40..0x1000),
|
||||
runtime _start 0x40001000. Payload `cc014efa…` flashed, cmp OK,
|
||||
vbutil body verification succeeded.
|
||||
|
||||
### Handoff
|
||||
|
||||
New `U-BOOT.md` in this repo: boot chain, payload layout constants,
|
||||
build/flash/verify command sequences, recovery paths, U-Boot tree
|
||||
state (kept features vs WIP/temporary), rotation and keyboard notes.
|
||||
The user owns the U-Boot config and further development.
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
# U-Boot on krane — final state and operating manual
|
||||
|
||||
Status as of 2026-08-30 (RESEARCH.md Rounds 1–36). Milestones reached:
|
||||
payload pipeline → framebuffer console → **USB pogo keyboard at the
|
||||
prompt → landscape (rotated 270°) console**, all verified on the
|
||||
device. The user owns the U-Boot config from here on.
|
||||
|
||||
## Boot chain
|
||||
|
||||
```
|
||||
BootROM → coreboot → TF-A BL31 → depthcharge (.12573.351.0)
|
||||
→ krane-uboot-payload.bin @ 0x40000000 (mmcblk0p1, devkeys)
|
||||
→ entry shim @ 0x40000040 → U-Boot _start @ 0x40001000
|
||||
→ banner + vidconsole3 prompt on the panel + usbkbd input
|
||||
```
|
||||
|
||||
The SPI firmware is never modified; only the kernel partition
|
||||
`mmcblk0p1` is reflashed.
|
||||
|
||||
## Payload layout (LOAD-BEARING constants)
|
||||
|
||||
| offset | content |
|
||||
|---|---|
|
||||
| 0x0000 | 64-byte arm64 Image header (code0 = `b +0x40`, image_size, flags bit3, magic `ARM\x64` at 0x38) |
|
||||
| 0x0040 | `uboot-wrapper.S` entry shim (OVL_EN=1, OVL0_2L_EN=1, backlight GPIOs 43/176 on, `b` to U-Boot — imm26 patched at build time) |
|
||||
| 0x1000 | `u-boot.bin` contiguous (no interior padding) |
|
||||
|
||||
- `CONFIG_TEXT_BASE=0x4C001000` (8-aligned, so no linker fill skews
|
||||
`_start`); the file is placed so runtime `_start = 0x40001000`
|
||||
(4K-aligned — required by U-Boot's PIE fixup, checked by the build
|
||||
script via `u-boot.sym`: `_start == __image_copy_start`).
|
||||
- The shim cannot be removed: depthcharge jumps to payload+0x40, and
|
||||
U-Boot cannot execute there (PIE/alignment). The diagnostic magenta
|
||||
fill + blink train + 5 s hold were removed in Round 37; the shim now
|
||||
only revives the display and branches.
|
||||
|
||||
## Build
|
||||
|
||||
### U-Boot
|
||||
|
||||
```sh
|
||||
cd /home/vhaudiquet/u-boot
|
||||
export CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm
|
||||
make mt8183_kukui_krane_defconfig # ONLY when changing the defconfig
|
||||
make -j8
|
||||
```
|
||||
|
||||
**Warning:** re-running the defconfig regenerates `.config` and wipes
|
||||
any hand edits. If you tune `.config` directly (like the current
|
||||
16×32 font setup), just run `make -j8`. After ANY defconfig edit +
|
||||
re-run, verify the full load-bearing set in `.config`:
|
||||
|
||||
```sh
|
||||
grep -E "CONFIG_USB=|DM_USB|XHCI|USB_KEYBOARD|USB_STORAGE|CMD_USB|USE_PREBOOT|PREBOOT=|PHY_MTK_TPHY|VIDEO_MT8183|CONSOLE_ROTATION|TEXT_BASE" .config
|
||||
grep -E " _start$|__image_copy_start" u-boot.sym # both 0x4c001000
|
||||
```
|
||||
|
||||
(Round 36 lesson: an elided-line edit dropped `CONFIG_USB=y` and USB
|
||||
silently disappeared.)
|
||||
|
||||
### Payload
|
||||
|
||||
```sh
|
||||
cd /home/vhaudiquet/krane-fb-stub
|
||||
./build-uboot-payload.sh
|
||||
```
|
||||
|
||||
Assembles header + wrapper + `u-boot.bin` → `krane-uboot-payload.bin`,
|
||||
packs with mkdepthcharge (devkeys, `PYTHONPATH=/root/krane-fb-stub/src/depthcharge-tools`),
|
||||
asserts `_start == 0x4C001000` from `u-boot.sym`, prints sha256.
|
||||
|
||||
### Flash + verify (always all three)
|
||||
|
||||
```sh
|
||||
SZ=$(stat -c%s krane-uboot-payload.bin)
|
||||
dd if=krane-uboot-payload.bin of=/dev/mmcblk0p1 bs=4M conv=fsync
|
||||
cmp -n $SZ krane-uboot-payload.bin /dev/mmcblk0p1 && echo CMP-OK
|
||||
futility vbutil_kernel --verify /dev/mmcblk0p1 # "Body verification succeeded"
|
||||
```
|
||||
|
||||
Then: reboot → depthcharge dev menu → "Internal storage".
|
||||
|
||||
### Recovery
|
||||
|
||||
- Backup of the original kernel partition:
|
||||
`~/mmcblk0p1-pmos-backup.img` (sha256 `20951a54…`), also on the USB
|
||||
stick (sda3). `dd` it back to `mmcblk0p1` to restore pmOS's FIT.
|
||||
- pmOS still boots from the USB stick (sda) via the depthcharge menu.
|
||||
- pmOS chroot lives on `mmcblk0p3`.
|
||||
|
||||
## U-Boot tree state (branch `krane`, on top of mainline 527115ef)
|
||||
|
||||
Kept features (upstreamable):
|
||||
|
||||
- `drivers/video/mt8183_scanout.c` — UCLASS_VIDEO scanout driver on
|
||||
the upstream `ovl0@14008000` node: revives the depthcharge scanout
|
||||
(OVL_EN/OVL0_2L_EN + backlight GPIOs), parses the coreboot table
|
||||
LBIO at `0xffed9000`, falls back to `OVL_L0_ADDR` (0x14008f40),
|
||||
sets `uc_priv->rot = 3` (270° CW landscape console).
|
||||
- `board/mediatek/mt8183/mt8183.c` — `get_page_table_size()` override
|
||||
(0x40000): the fb and coreboot-table dynamic mappings exhaust the
|
||||
default page-table budget (Round 31). Any new post-reloc
|
||||
`mmu_map_region` relies on this headroom.
|
||||
- `arch/arm/dts/mt8183-kukui-krane-sku176-u-boot.dtsi` — overlay (NOT
|
||||
a DT fork): adds `simple-mfd` to the mtu3 ssusb node (so DM scans
|
||||
its children and binds xhci — Round 34) and `ippc` reg + `phys` on
|
||||
`usb@11200000` (what `xhci-mtk.c` expects; upstream puts those on
|
||||
the parent for Linux's mtu3 driver).
|
||||
- `board/mediatek/mt8183/krane.env` — `stdin=serial,usbkbd`,
|
||||
`stdout=serial,vidconsole`, `stderr=serial,vidconsole`.
|
||||
- defconfig: USB stack (`USB`, `DM_USB`, `USB_XHCI_HCD`,
|
||||
`USB_XHCI_MTK`, `USB_KEYBOARD`, `USB_STORAGE`, `CMD_USB`),
|
||||
`PHY_MTK_TPHY`, `USE_PREBOOT` (preboot defaults to `usb start`),
|
||||
`CONSOLE_ROTATION`, `ENV_IS_NOWHERE` + `ENV_SOURCE_FILE="krane"`.
|
||||
|
||||
Still WIP/temporary in the tree (revert before upstreaming; see
|
||||
`git log --oneline | grep -i wip`):
|
||||
|
||||
- fb text logger + diag bands (`krane_fb_log`/`krane_diag_band` in
|
||||
mt8183_scanout.c, band calls in video-uclass.c/board_f.c/main.c/
|
||||
mt8183.c), abort dump hook in `interrupts_64.c` (`do_sync` draws
|
||||
ESR/ELR/FAR on the panel),
|
||||
- `CONFIG_PANIC_HANG=y` (freeze + dump on abort; production wants it
|
||||
off — otherwise panic silently resets),
|
||||
- `CONFIG_WATCHDOG_AUTOSTART=n` (decide for production),
|
||||
- `CONFIG_BOARD_LATE_INIT=y` (only used by a diag band).
|
||||
|
||||
## Behavior notes
|
||||
|
||||
- Console: 16×32 font (user's `.config`), white-on-black, rotated
|
||||
270° CW ⇒ landscape 60×75 text grid. To change rotation:
|
||||
`uc_priv->rot` in `mt8183_scanout_probe` (0=portrait-native,
|
||||
1/3=the two landscape orientations, 2=upside-down portrait).
|
||||
- Keyboard: pogo keyboard = USB HID behind the GL610 hub on
|
||||
`usb@11200000`. Enumeration happens at preboot (`usb start`); the
|
||||
usb_kbd probe re-muxes `stdin` from the env. If keys die, first
|
||||
check `.config` still has the full USB set (Round 36).
|
||||
- USB stick (sda) enumerates too (`USB_STORAGE`) — distro_bootcmd is
|
||||
the next milestone.
|
||||
- MMIO 0x0–0x20000000 is pre-mapped device memory (armv8-mem-map.c);
|
||||
only DRAM-above-0x40000000/`0xffed9000` regions need dynamic
|
||||
`mmu_map_region` (done in the scanout driver).
|
||||
|
||||
## The 2021-era display handoff (why the shim exists)
|
||||
|
||||
depthcharge (device-era, R93) `display_cleanup()` before the jump:
|
||||
`clear_screen(black)`, backlight GPIOs low, `OVL_EN=0` (0x14008000+0xc),
|
||||
`OVL0_2L_EN=0` (+0x100c). `OVL_L0_ADDR` (+0xf40) still holds the menu
|
||||
scanout address. Both the shim and the scanout driver undo this; the
|
||||
panel/DSI link is never reinitialized.
|
||||
|
||||
## Quick reference
|
||||
|
||||
```sh
|
||||
# change rotation / code, then:
|
||||
cd /home/vhaudiquet/u-boot && export CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm && make -j8
|
||||
cd /home/vhaudiquet/krane-fb-stub && ./build-uboot-payload.sh
|
||||
SZ=$(stat -c%s krane-uboot-payload.bin) && \
|
||||
dd if=krane-uboot-payload.bin of=/dev/mmcblk0p1 bs=4M conv=fsync && \
|
||||
cmp -n $SZ krane-uboot-payload.bin /dev/mmcblk0p1 && \
|
||||
futility vbutil_kernel --verify /dev/mmcblk0p1
|
||||
```
|
||||
@@ -4,8 +4,8 @@
|
||||
# 0x0000 64-byte arm64 Image header (code0 = b +0x40, image_size,
|
||||
# flags bit3, magic at 0x38 — booting.rst contract, verified
|
||||
# against depthcharge src/arch/arm/boot64.c)
|
||||
# 0x0040 uboot-wrapper.S (diagnostic: revive display + magenta fill +
|
||||
# blink train, then branch to U-Boot; branch imm26 patched)
|
||||
# 0x0040 uboot-wrapper.S (entry shim: revive display, branch to
|
||||
# U-Boot; branch imm26 patched)
|
||||
# 0x0040+ uboot.bin (u-boot-nodtb.bin + embedded control DTB),
|
||||
# contiguous — NO interior padding.
|
||||
#
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+15
-70
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* krane diagnostic wrapper — runs before U-Boot proper after the
|
||||
* krane payload entry shim — runs at 0x40000040 right after the
|
||||
* depthcharge handoff (MMU off, caches off; position-independent:
|
||||
* immediate-encoded addresses only).
|
||||
*
|
||||
* Purpose: prove that the payload actually executes and revive the
|
||||
* display before U-Boot gets a chance to crash, so a dark screen can be
|
||||
* attributed unambiguously:
|
||||
* - magenta screen + backlight on, 3 slow blinks, magenta held ~5 s,
|
||||
* then U-Boot takes over: wrapper ran
|
||||
* - blink train repeating periodically: watchdog reset loop
|
||||
* - dark screen, no blink train: wrapper never executed
|
||||
* depthcharge's display_cleanup() stops the overlay engines and drops
|
||||
* the backlight before jumping to the payload; this shim undoes those
|
||||
* writes so the screen stays alive until U-Boot's scanout driver
|
||||
* probes (the driver repeats the revival itself). The shim cannot be
|
||||
* removed: depthcharge jumps to payload+0x40, while U-Boot's PIE
|
||||
* fixup needs its runtime _start 4K-aligned — so U-Boot sits at image
|
||||
* offset 0x1000 and this shim branches there (branch imm26 patched at
|
||||
* build time by build-uboot-payload.sh).
|
||||
*
|
||||
* Register sources (all verified on device, see RESEARCH.md rounds 4/10):
|
||||
* OVL0 base 0x14008000: OVL_EN @ +0x000c, OVL0_2L_EN @ +0x100c,
|
||||
* OVL_L0_ADDR @ +0x0f40 (depthcharge device-era mtk_ddp.c).
|
||||
* Register sources (all verified on device, RESEARCH.md rounds 4/10):
|
||||
* OVL0 base 0x14008000: OVL_EN @ +0x000c, OVL0_2L_EN @ +0x100c
|
||||
* (device-era depthcharge mtk_ddp.c offsets).
|
||||
* GPIO controller 0x10005000, dout block +0x100, 16 B per 32-pin
|
||||
* group, set @ +4 / rst @ +8 (mt8183.h GpioRegs):
|
||||
* DISP_PWM = pin 43 (bit 11, set 0x10005114 / rst 0x10005118),
|
||||
* EN_LCD_BL = pin 176 (bit 16, set 0x10005154 / rst 0x10005158).
|
||||
* Scanout geometry: 1200*1920, 32bpp xRGB, 0x8ca000 bytes.
|
||||
* group, set @ +4 (mt8183.h GpioRegs):
|
||||
* DISP_PWM = pin 43 (bit 11, set 0x10005114),
|
||||
* EN_LCD_BL = pin 176 (bit 16, set 0x10005154).
|
||||
*/
|
||||
|
||||
.text
|
||||
@@ -43,59 +43,4 @@ _start:
|
||||
mov w3, #0x5154
|
||||
movk w3, #0x1000, lsl #16
|
||||
str w2, [x3]
|
||||
/* live scanout address: OVL_L0_ADDR = 0x14008f40 */
|
||||
mov w3, #0x8f40
|
||||
movk w3, #0x1400, lsl #16
|
||||
ldr w4, [x3]
|
||||
/* fill only when the address looks like DRAM (>= 0x40000000) */
|
||||
mov w5, #0x4000
|
||||
movk w5, #0x4000, lsl #16
|
||||
cmp w4, w5
|
||||
b.lo 1f
|
||||
/* fill the scanout with magenta (0x00ff00ff): 0x8ca000/4 words */
|
||||
mov w2, #0xff
|
||||
movk w2, #0xff00, lsl #16
|
||||
mov x6, #0x2800
|
||||
movk x6, #0x23, lsl #16
|
||||
2: str w2, [x4], #4
|
||||
subs x6, x6, #1
|
||||
b.ne 2b
|
||||
/* blink the backlight 3x: repeating trains reveal a reset loop */
|
||||
mov w11, #3
|
||||
6: mov w2, #0x800
|
||||
mov w3, #0x5118
|
||||
movk w3, #0x1000, lsl #16
|
||||
str w2, [x3]
|
||||
mov w2, #0x10000
|
||||
mov w3, #0x5158
|
||||
movk w3, #0x1000, lsl #16
|
||||
str w2, [x3]
|
||||
bl delay
|
||||
mov w2, #0x800
|
||||
mov w3, #0x5114
|
||||
movk w3, #0x1000, lsl #16
|
||||
str w2, [x3]
|
||||
mov w2, #0x10000
|
||||
mov w3, #0x5154
|
||||
movk w3, #0x1000, lsl #16
|
||||
str w2, [x3]
|
||||
bl delay
|
||||
subs w11, w11, #1
|
||||
b.ne 6b
|
||||
/* hold magenta for ~5 s so the phase cannot be missed */
|
||||
mov w12, #20
|
||||
7: bl delay
|
||||
subs w12, w12, #1
|
||||
b.ne 7b
|
||||
1: b . /* PATCHED: branch to U-Boot entry */
|
||||
|
||||
/* ~250 ms delay using the arch timer */
|
||||
delay:
|
||||
mrs x7, cntfrq_el0
|
||||
lsr x7, x7, #2
|
||||
mrs x8, cntvct_el0
|
||||
add x8, x8, x7
|
||||
9: mrs x9, cntvct_el0
|
||||
cmp x9, x8
|
||||
b.lo 9b
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user