How the vendored U-Boot finds a kernel (task 1.3) ================================================== Read from k230_linux_sdk @ dev, buildroot-overlay/board/canaan/k230-soc/env/default.env, which k230_canmv_v3_defconfig writes to the card at 3M and 3.5M. bootcmd = run blinux; blinux = k230_set_dtb && ext4load mmc ${mmc_boot_dev_num}:1 0x3000000 /fw_jump_add_uboot_head.bin && ext4load mmc ${mmc_boot_dev_num}:1 0x200000 /${k} && ext4load mmc ${mmc_boot_dev_num}:1 0x2200000 /${dtb} && bootm 0x3000000 - 0x2200000; mmc_boot_dev_num = 1 k = Image dtb = force.dtb baudrate = 115200 console_port = console=ttyS1,115200 So stage 1 expects, on the FIRST partition of mmc 1, an ext4 filesystem containing exactly three files at its root: /fw_jump_add_uboot_head.bin OpenSBI fw_jump with a U-Boot image header, made with `mkimage -A riscv -O linux -T kernel -C none -a 0 -e 0 -n linux -d fw_jump.bin` /Image the kernel /force.dtb the device tree `bootm 0x3000000 - 0x2200000` boots the OpenSBI payload with that dtb; OpenSBI then enters the kernel. `k230_set_dtb` is a Canaan-added U-Boot command. IT IS NOT EXTLINUX ------------------- This overturns the choice made in a-riscv-nixos-closure-cross-builds, where nix/hardware.nix used boot.loader.generic-extlinux-compatible on the assumption that vendored U-Boot reads extlinux. It does not: the default environment runs a hardcoded `blinux` command and never calls `sysboot`. Two ways out, and the spec picks the first: (a) Match the filenames. Put Image, force.dtb and fw_jump_add_uboot_head.bin at the root of the boot ext4 and leave stage 1 untouched. image/boot-chain requires our kernel to be loaded "without modification to stage 1 itself", so this is the conforming option. (b) Rewrite the U-Boot environment to use extlinux. Cleaner in NixOS terms -- generations would work the way they do everywhere else -- but it modifies vendored firmware, which the spec forbids, and the env lives in two raw copies at 3M and 3.5M. CONSOLE: ttyS1, NOT ttyS0 -- to be verified -------------------------------------------- The SDK default sets console_port=console=ttyS1,115200. Our system currently passes console=ttyS0,115200n8, which is what the QEMU virt machine uses. These may disagree because the CanMV-K230 reference board and the T-Display-K230 need not put the Linux console on the same UART. On this board the CH342 bridge channel 0 goes to K230 UART0 and channel 1 to UART3 (docs/findings.md), and the RT-Smart U-Boot printed on serial@91400000. Unresolved, and cheap to get wrong: a console on the wrong UART looks exactly like a board that did not boot. Plan to try ttyS0 first, and on silence try ttyS1 before suspecting the image. SD LAYOUT (task 2.1) --------------------- From buildroot-overlay/board/canaan/k230-soc/genimage_cfg/genimage.cfg. MBR. offset 1M (0x100000) u-boot SPL, raw, not in the partition table offset 1.5M (0x180000) u-boot SPL again -- a second copy offset 2M (0x200000) u-boot proper, raw offset 3M (0x300000) env, 128K, raw offset 3.5M (0x320000) env again, 128K, raw offset 4M boot.ext4, 80M, MBR type 0x83 <- mmc 1:1 offset 128M rootfs.ext4, MBR type 0x83 The `fn_` prefix on the SPL and u-boot images means a Canaan firmware header has been added by add_firmHead(), which calls output//build/uboot-2022.10/tools/firmware_gen_no_securiy.py. This is NOT the RT-Smart layout. The shipped LilyGO image had raw firmware in sectors 0-102399 and two FAT32 partitions at 102400 and 163840 (docs/findings.md). Stage 1 is configured differently for the two payload types, which is why the Linux SDK's build was chosen over extracting firmware from the RT-Smart image. === Source splash integration (2026-09-22) === The RM69A10 U-Boot logo path optionally reads /logo.xrgb from the boot partition before loading Linux. Format: 568x1232 XRGB8888, little-endian B,G,R,X bytes, exactly 2799104 bytes. The address comes from nix/boot-splash.nix (currently 0x10000000), selected against docs/evidence/stage1-memory-map.md. The loader checks ext4size before writing and limits ext4load to the exact size; a missing or malformed asset skips the logo without preventing normal boot. k230.panelConsole=true omits logo.xrgb and puts console=tty0 first in the command line, retaining the serial console as primary. This remains the daily default while splash acceptance is incomplete. Setting the option false includes the asset and leaves kernel text on serial. The hardware stage-1 splash is observed; seamless Linux handoff remains unverified. See docs/evidence/boot-splash-handoff.md and the diagnostic trial below. === Splash-enabled image contents (2026-09-22; host-side artifact proof) === The isolated diagnostic image at source 671d404 includes /logo.xrgb beside Image, initrd.uimg and k230-tdisplay.dtb. Its 112 MiB boot partition starts at 4 MiB, as nix/sd-image.nix defines; the 80 MiB figure above describes the original SDK layout. The copied asset is exactly 2799104 bytes and hashes to 6c7a36086297597b359657ab53925ee0725e5201461484d543cbd950f5baa3af. See docs/evidence/splash-preserve-trial/build.txt and image-contents.txt for the successful nix build .#sdImage and debugfs inspection. This inspection reads the immutable host image, not the card, and is not a flash readback. The default daily image is still the verified no-logo configuration pending physical acceptance of the diagnostic handoff.