176 lines
7.6 KiB
Markdown
176 lines
7.6 KiB
Markdown
# 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-updates`, 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 43/176), parses the coreboot
|
||
table LBIO at `0xffed9000`, falls back to `OVL_L0_ADDR` (0x14008f40),
|
||
sets `uc_priv->rot = 3` (270° CW landscape console). The shared
|
||
handoff code lives in `mt8183_disp.c` / `mt8183_disp.h`.
|
||
- `drivers/video/mt8183_display.c` — full cold bring-up driver
|
||
(Kconfig choice `VIDEO_MT8183_DISPLAY`, now the defconfig default;
|
||
`VIDEO_MT8183_SCANOUT` keeps the old behavior): MMSYS display gates,
|
||
SMI LARB0, panel init via `drivers/video/mtk_dsi.c` +
|
||
`drivers/phy/phy-mtk-mipi-tx.c` + `drivers/video/panel_boe_tv101wum.c`,
|
||
overlay scanout of a framebuffer at 0xFC000000 (FDT memreserve +
|
||
LMB), backlight. Falls back to the handoff revival, logging the
|
||
stage. Serial prints: `[dsi] phase 0/9/F`.
|
||
- `drivers/gpio/mt8183_gpio.c` — minimal MT8183 GPIO driver (dir/dout/
|
||
din; pinmux left to firmware) for the panel reset / supply-enable pads.
|
||
- `drivers/clk/mediatek/clk-mt8183.c` — now also models the MMSYS
|
||
display gates (CLK_MM_*) as a clock provider on `mmsys@14000000`.
|
||
- `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
|
||
```
|