diff --git a/README.md b/README.md index 377fb8a..2e41302 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ 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 | +| 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-c2/board.conf b/boards/odroid-c2/board.conf new file mode 100644 index 0000000..e418102 --- /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 0000000..d71cca8 --- /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 0000000..76c87d3 --- /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 0000000..d55b450 --- /dev/null +++ b/boards/odroid-c2/target-packages.txt @@ -0,0 +1,2 @@ +net-misc/openssh +sys-apps/busybox diff --git a/boards/odroid-c4/board.conf b/boards/odroid-c4/board.conf new file mode 100644 index 0000000..54427ac --- /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 0000000..aed2654 --- /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 0000000..bd06482 --- /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 0000000..d55b450 --- /dev/null +++ b/boards/odroid-c4/target-packages.txt @@ -0,0 +1,2 @@ +net-misc/openssh +sys-apps/busybox diff --git a/crossdev-stages/src/bootloader/amlogic_fip.rs b/crossdev-stages/src/bootloader/amlogic_fip.rs index 44a5c49..ba6feaa 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, ))?;