From 5dcd17998ec17974cfe911b6c8b4baff8512176c Mon Sep 17 00:00:00 2001 From: Sungjoon Moon Date: Fri, 3 Jul 2026 10:38:03 +0900 Subject: [PATCH 1/3] bootloader/amlogic-fip: pack built TF-A BL31 instead of shipped blob Co-Authored-By: Claude Fable 5 --- crossdev-stages/src/bootloader/amlogic_fip.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crossdev-stages/src/bootloader/amlogic_fip.rs b/crossdev-stages/src/bootloader/amlogic_fip.rs index 44a5c495..ba6feaae 100644 --- a/crossdev-stages/src/bootloader/amlogic_fip.rs +++ b/crossdev-stages/src/bootloader/amlogic_fip.rs @@ -20,9 +20,19 @@ pub fn clone(runner: &SandboxRunner, board: &BoardConfig) -> Result<()> { pub fn build(runner: &SandboxRunner, board: &BoardConfig, _env: &[String]) -> Result<()> { if board.fip_repo.is_some() { + // build-fip.sh only takes BL33; the remaining blobs come from the + // repo's per-board directory. When the tfa stage built a BL31, + // substitute it for the shipped one before packing. + let bl31 = match (&board.tfa_repo, &board.tfa_plat) { + (Some(_), Some(plat)) => format!( + "cp /build/tfa/build/{plat}/release/bl31.bin /build/fip/{name}/bl31.bin && ", + name = board.name, + ), + _ => String::new(), + }; runner.run(&format!( "mkdir -p /build/u-boot-sd && \ - cd /build/fip && \ + {bl31}cd /build/fip && \ ./build-fip.sh {board} /build/u-boot/u-boot.bin /build/u-boot-sd/", board = board.name, ))?; From 79a815d8bd9c82550bb8f9408b62697eb788dcc8 Mon Sep 17 00:00:00 2001 From: Sungjoon Moon Date: Fri, 24 Apr 2026 03:13:57 +0900 Subject: [PATCH 2/3] boards/odroid-c2: add Hardkernel Odroid-C2 (Amlogic S905) Co-Authored-By: Claude Opus 4.7 (1M context) Co-Authored-By: Claude Fable 5 --- README.md | 1 + boards/odroid-c2/board.conf | 45 ++++++++++++++++++++ boards/odroid-c2/genimage.cfg | 61 ++++++++++++++++++++++++++++ boards/odroid-c2/post-assemble.sh | 15 +++++++ boards/odroid-c2/target-packages.txt | 2 + 5 files changed, 124 insertions(+) create mode 100644 boards/odroid-c2/board.conf create mode 100644 boards/odroid-c2/genimage.cfg create mode 100644 boards/odroid-c2/post-assemble.sh create mode 100644 boards/odroid-c2/target-packages.txt diff --git a/README.md b/README.md index 377fb8a1..50dad440 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Rootless cross-compilation of Gentoo stages using crossdev and hakoniwa | odroid-m1 | aarch64 | mainline v7.0 | TFA + U-Boot + rkbin | `-O3 -mcpu=cortex-a55` | testing | | odroid-m1s | aarch64 | mainline v7.0 | TFA + U-Boot + rkbin | `-O3 -mcpu=cortex-a55` | testing | | odroid-m2 | aarch64 | mainline v7.0 | TFA + U-Boot + rkbin | `-O3 -mcpu=cortex-a76.cortex-a55` | testing | +| odroid-c2 | aarch64 | mainline v7.0 | TFA + U-Boot + amlogic-fip | `-O2 -mcpu=cortex-a53` | testing | | pentium-mmx | i586 | mainline v6.12 | BIOS (no firmware) | `-O2 -march=pentium-mmx` | testing | ## CLI diff --git a/boards/odroid-c2/board.conf b/boards/odroid-c2/board.conf new file mode 100644 index 00000000..e418102b --- /dev/null +++ b/boards/odroid-c2/board.conf @@ -0,0 +1,45 @@ +TESTING="true" + +BOARD_NAME="odroid-c2" +BOARD_ARCH="aarch64" +BOARD_CFLAGS="-O2 -mcpu=cortex-a53 -pipe" +CROSS_COMPILE="aarch64-unknown-linux-gnu-" +KERNEL_ARCH="arm64" + +# Mainline kernel (Amlogic GXBB / S905 has upstream support) +KERNEL_REPO="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" +KERNEL_TAG="v7.0" +KERNEL_DEFCONFIG="defconfig" + +# Mainline U-Boot supports odroid-c2 since v2017.09 +U_BOOT_REPO="https://github.com/u-boot/u-boot.git" +U_BOOT_TAG="v2026.04" +U_BOOT_DEFCONFIG="odroid-c2_defconfig" + +# BL31 from mainline ARM Trusted Firmware (Amlogic GXBB plat). +TFA_REPO="https://github.com/ARM-software/arm-trusted-firmware.git" +TFA_TAG="lts-v2.14.1" +TFA_PLAT="gxbb" + +# BL2/BL30/BL301 are Amlogic-signed vendor blobs (not available in source). +# LibreELEC/amlogic-boot-fip bundles these plus fip_create/aml_encrypt_gxb. +# The amlogic-fip pipeline stage copies our TF-A bl31.bin over the shipped +# one, then runs build-fip.sh. +FIP_REPO="https://github.com/LibreELEC/amlogic-boot-fip.git" + +# Build order: BL31 (TF-A) -> U-Boot -> amlogic-fip packs everything. +BOOT_PIPELINE=("tfa" "uboot" "amlogic-fip") + +BOARD_DTB_GLOB="arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dtb" + +# Boot +BOOT_ROOT_DEV="/dev/mmcblk0p2" +BOOT_CONSOLE="ttyAML0,115200" +BOOT_KERNEL_NAME="Image" + +BUILD_STEPS=(deps checkout bootloader kernel assemble pack) + +BOOT_SERVICES=("sshd:default" "metalog:default" "ntp-client:default") +BOOT_HOSTNAME="gentoo" +BOOT_SERIAL_TTY="ttyAML0" +BOOT_SERIAL_BAUD="115200" diff --git a/boards/odroid-c2/genimage.cfg b/boards/odroid-c2/genimage.cfg new file mode 100644 index 00000000..d71cca8e --- /dev/null +++ b/boards/odroid-c2/genimage.cfg @@ -0,0 +1,61 @@ +config { + outputpath = . + inputpath = . + rootpath = gen + tmppath = tmp +} + +image rootfs.ext4 { + ext4 { + use-mke2fs = "true" + label = "rootfs" + extraargs = "-i 4k" + } + + size = 3G + mountpoint = "/root" +} + +image bootfs.ext4 { + ext4 { + use-mke2fs = "true" + label = "bootfs" + } + + size = 128M + mountpoint = "/boot" +} + +/* Amlogic SD layout: BL1 spans sectors 0-96 and the FIP+u-boot starts at + * sector 97, so the first usable partition must clear ~50 KiB. GPT is not + * usable here (its primary header at sector 1 collides with BL1). */ +image gentoo-linux-odroid-c2_dev-sdcard.img { + hdimage { + partition-table-type = mbr + } + + partition bootloader { + image = "u-boot-sd/u-boot.bin.sd.bin" + offset = "0" + /* MBR partition table lives at bytes 440-511. */ + holes = "(440; 512)" + in-partition-table = "false" + } + + partition bootfs { + image = "bootfs.ext4" + offset = "4M" + size = "128M" + partition-type = 0x83 + bootable = "true" + in-partition-table = "true" + } + + partition rootfs { + image = "rootfs.ext4" + offset = "132M" + size = "" + partition-type = 0x83 + in-partition-table = "true" + } +} diff --git a/boards/odroid-c2/post-assemble.sh b/boards/odroid-c2/post-assemble.sh new file mode 100644 index 00000000..76c87d3e --- /dev/null +++ b/boards/odroid-c2/post-assemble.sh @@ -0,0 +1,15 @@ +set -e + +# extlinux boot config (U-Boot distroboot picks this up from bootfs) +mkdir -p /build/gen/boot/extlinux +kver=$(ls /build/gen/root/lib/modules/ | head -1) +[ -z "$kver" ] && { echo 'Error: no kernel modules found'; exit 1; } +cat > /build/gen/boot/extlinux/extlinux.conf << EXTEOF +DEFAULT gentoo +TIMEOUT 30 +LABEL gentoo + MENU LABEL Gentoo Linux + LINUX /${BOOT_KERNEL_NAME} + FDT /meson-gxbb-odroidc2.dtb + APPEND root=${BOOT_ROOT_DEV} rw rootwait rootfstype=ext4 console=${BOOT_CONSOLE} earlycon +EXTEOF diff --git a/boards/odroid-c2/target-packages.txt b/boards/odroid-c2/target-packages.txt new file mode 100644 index 00000000..d55b4501 --- /dev/null +++ b/boards/odroid-c2/target-packages.txt @@ -0,0 +1,2 @@ +net-misc/openssh +sys-apps/busybox From c58d7034beeaf47c54ade203479f63a59f9dd156 Mon Sep 17 00:00:00 2001 From: Sungjoon Moon Date: Fri, 24 Apr 2026 03:14:19 +0900 Subject: [PATCH 3/3] boards/odroid-c4: add Hardkernel Odroid-C4 (Amlogic S905X3) Co-Authored-By: Claude Opus 4.7 (1M context) Co-Authored-By: Claude Fable 5 --- README.md | 1 + boards/odroid-c4/board.conf | 41 +++++++++++++++++++ boards/odroid-c4/genimage.cfg | 61 ++++++++++++++++++++++++++++ boards/odroid-c4/post-assemble.sh | 15 +++++++ boards/odroid-c4/target-packages.txt | 2 + 5 files changed, 120 insertions(+) create mode 100644 boards/odroid-c4/board.conf create mode 100644 boards/odroid-c4/genimage.cfg create mode 100644 boards/odroid-c4/post-assemble.sh create mode 100644 boards/odroid-c4/target-packages.txt diff --git a/README.md b/README.md index 50dad440..2e413026 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Rootless cross-compilation of Gentoo stages using crossdev and hakoniwa | odroid-m1s | aarch64 | mainline v7.0 | TFA + U-Boot + rkbin | `-O3 -mcpu=cortex-a55` | testing | | odroid-m2 | aarch64 | mainline v7.0 | TFA + U-Boot + rkbin | `-O3 -mcpu=cortex-a76.cortex-a55` | testing | | odroid-c2 | aarch64 | mainline v7.0 | TFA + U-Boot + amlogic-fip | `-O2 -mcpu=cortex-a53` | testing | +| odroid-c4 | aarch64 | mainline v7.0 | U-Boot + amlogic-fip | `-O2 -mcpu=cortex-a55` | testing | | pentium-mmx | i586 | mainline v6.12 | BIOS (no firmware) | `-O2 -march=pentium-mmx` | testing | ## CLI diff --git a/boards/odroid-c4/board.conf b/boards/odroid-c4/board.conf new file mode 100644 index 00000000..54427ac4 --- /dev/null +++ b/boards/odroid-c4/board.conf @@ -0,0 +1,41 @@ +TESTING="true" + +BOARD_NAME="odroid-c4" +BOARD_ARCH="aarch64" +BOARD_CFLAGS="-O2 -mcpu=cortex-a55 -pipe" +CROSS_COMPILE="aarch64-unknown-linux-gnu-" +KERNEL_ARCH="arm64" + +# Mainline kernel (Amlogic SM1 / S905X3 has upstream support). +KERNEL_REPO="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" +KERNEL_TAG="v7.0" +KERNEL_DEFCONFIG="defconfig" + +# Mainline U-Boot supports odroid-c4 since v2020.10. +U_BOOT_REPO="https://github.com/u-boot/u-boot.git" +U_BOOT_TAG="v2026.04" +U_BOOT_DEFCONFIG="odroid-c4_defconfig" + +# SM1 uses g12a FIP flow with bl31.img (Amlogic-packaged BL31) + DDR +# training blobs. Mainline TF-A supports plat=g12a but a bl31.bin +# -> bl31.img converter isn't wired up; we use the pre-built bl31.img +# shipped in amlogic-boot-fip. TODO: optional TFA stage once the +# converter exists. +FIP_REPO="https://github.com/LibreELEC/amlogic-boot-fip.git" + +# Build order: U-Boot -> amlogic-fip packs U-Boot + shipped bl31.img + vendor blobs. +BOOT_PIPELINE=("uboot" "amlogic-fip") + +BOARD_DTB_GLOB="arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dtb" + +# Boot +BOOT_ROOT_DEV="/dev/mmcblk0p2" +BOOT_CONSOLE="ttyAML0,115200" +BOOT_KERNEL_NAME="Image" + +BUILD_STEPS=(deps checkout bootloader kernel assemble pack) + +BOOT_SERVICES=("sshd:default" "metalog:default" "ntp-client:default") +BOOT_HOSTNAME="gentoo" +BOOT_SERIAL_TTY="ttyAML0" +BOOT_SERIAL_BAUD="115200" diff --git a/boards/odroid-c4/genimage.cfg b/boards/odroid-c4/genimage.cfg new file mode 100644 index 00000000..aed26545 --- /dev/null +++ b/boards/odroid-c4/genimage.cfg @@ -0,0 +1,61 @@ +config { + outputpath = . + inputpath = . + rootpath = gen + tmppath = tmp +} + +image rootfs.ext4 { + ext4 { + use-mke2fs = "true" + label = "rootfs" + extraargs = "-i 4k" + } + + size = 3G + mountpoint = "/root" +} + +image bootfs.ext4 { + ext4 { + use-mke2fs = "true" + label = "bootfs" + } + + size = 128M + mountpoint = "/boot" +} + +/* Amlogic SM1 SD boot layout: same as GXBB -- u-boot.bin.sd.bin goes at + * offset 0 with a hole in bytes 440-512 so genimage can write its MBR + * partition table. First partition starts at 4 MiB to clear the bootloader. + */ +image gentoo-linux-odroid-c4_dev-sdcard.img { + hdimage { + partition-table-type = mbr + } + + partition bootloader { + image = "u-boot-sd/u-boot.bin.sd.bin" + offset = "0" + holes = "(440; 512)" + in-partition-table = "false" + } + + partition bootfs { + image = "bootfs.ext4" + offset = "4M" + size = "128M" + partition-type = 0x83 + bootable = "true" + in-partition-table = "true" + } + + partition rootfs { + image = "rootfs.ext4" + offset = "132M" + size = "" + partition-type = 0x83 + in-partition-table = "true" + } +} diff --git a/boards/odroid-c4/post-assemble.sh b/boards/odroid-c4/post-assemble.sh new file mode 100644 index 00000000..bd064829 --- /dev/null +++ b/boards/odroid-c4/post-assemble.sh @@ -0,0 +1,15 @@ +set -e + +# extlinux boot config (U-Boot distroboot picks this up from bootfs) +mkdir -p /build/gen/boot/extlinux +kver=$(ls /build/gen/root/lib/modules/ | head -1) +[ -z "$kver" ] && { echo 'Error: no kernel modules found'; exit 1; } +cat > /build/gen/boot/extlinux/extlinux.conf << EXTEOF +DEFAULT gentoo +TIMEOUT 30 +LABEL gentoo + MENU LABEL Gentoo Linux + LINUX /${BOOT_KERNEL_NAME} + FDT /meson-sm1-odroid-c4.dtb + APPEND root=${BOOT_ROOT_DEV} rw rootwait rootfstype=ext4 console=${BOOT_CONSOLE} earlycon +EXTEOF diff --git a/boards/odroid-c4/target-packages.txt b/boards/odroid-c4/target-packages.txt new file mode 100644 index 00000000..d55b4501 --- /dev/null +++ b/boards/odroid-c4/target-packages.txt @@ -0,0 +1,2 @@ +net-misc/openssh +sys-apps/busybox