Files

176 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# U-Boot on krane — final state and operating manual
Status as of 2026-08-30 (RESEARCH.md Rounds 136). 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 0x00x20000000 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
```