Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 225 additions & 0 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
name: Create SD Card Images

on:
workflow_dispatch:
inputs:
board:
description: 'Board to create image for'
type: choice
required: true
options:
- raspberry-pi-4
default: 'raspberry-pi-4'
use_latest_release:
description: 'Use latest release artifacts instead of workflow artifacts'
type: boolean
default: false
pull_request:
types: [labeled]
jobs:
create-image:
name: Create SD Card Image for ${{ inputs.board }}
runs-on: ubuntu-latest
#runs-on: [ self-hosted, latest ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
clean: true
fetch-depth: 0
submodules: recursive

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
genimage \
u-boot-tools \
parted \
gdisk \
qemu-utils \
dosfstools \
e2fsprogs \
genext2fs \
mtools \
jq

- name: Prepare build environment
run: |
# Set up directory structure similar to buildroot build
mkdir -p output/images
mkdir -p build

- name: Set bootloader and target based on board
run: |
#case "${{ inputs.board }}" in
case "raspberry-pi-4" in
raspberry-pi-4)
echo "BOOTLOADER=rpi4_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV
;;
*)
echo "Error: Unknown board ${{ inputs.board }}"
exit 1
;;
esac
echo "Using bootloader: $BOOTLOADER and target: $TARGET for board: ${{ inputs.board }}"

- name: Download bootloader artifacts
if: ${{ !inputs.use_latest_release }}
run: |
# Download from latest bootloader build workflow on main branch
#gh run list --workflow=build-boot.yml --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_boot_run_id
gh run list --workflow=build-boot.yml --branch=create-sdcard --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_boot_run_id
BOOT_RUN_ID=$(cat latest_boot_run_id)

gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER} --dir temp_bootloader/

# Extract bootloader directly to output/images
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/

echo "Bootloader files extracted to output/images:"
ls -la output/images/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Download Infix artifacts
if: ${{ !inputs.use_latest_release }}
run: |
# Download from latest Kernelkit Trigger workflow for main branch
#gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
gh run list --workflow=164295764 --branch=create-sdcard --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
INFIX_RUN_ID=$(cat latest_infix_run_id)

gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/

# Extract Infix directly to output/images
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/

echo "Infix files extracted to output/images:"
ls -la output/images/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Download from latest releases
if: ${{ inputs.use_latest_release }}
run: |
# Download latest bootloader release
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/

# Download latest Infix release
gh release download latest --pattern "*${TARGET}*" --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/

echo "All files extracted to output/images:"
ls -la output/images/
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Verify extracted files
run: |
echo "Files available for mkimage.sh:"
ls -la output/images/
echo ""
echo "File types:"
file output/images/* || true

- name: Create SD card image
run: |
export BINARIES_DIR=$PWD/output/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"

# Use the standardized mkimage.sh path for the selected board
# BOARD_SCRIPT="src/board/${{ inputs.board }}/mkimage.sh"
BOARD_SCRIPT="src/board/raspberry-pi-4/mkimage.sh"

if [ -f "$BOARD_SCRIPT" ]; then
echo "Using board-specific image creation script: $BOARD_SCRIPT"
chmod +x "$BOARD_SCRIPT"
"$BOARD_SCRIPT"
else
echo "Error: Board script $BOARD_SCRIPT not found!"
exit 1
fi

- name: Verify created image
run: |
echo "Contents of output/images after mkimage.sh:"
ls -lh output/images/

# Look for SD card image with pattern: *-sdcard.img
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then
echo "Found SD card image(s):"
for img in output/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
else
echo "No SD card image found matching pattern: *-sdcard.img"
echo "Available files:"
ls -la output/images/
exit 1
fi

- name: Upload SD card image
uses: actions/upload-artifact@v4
with:
name: sdcard-image-${{ inputs.board }}-${{ env.BOOTLOADER }}
path: |
output/images/*-sdcard.img
retention-days: 30

- name: Create checksums
run: |
cd output/images/
for file in *-sdcard.img; do
if [ -f "$file" ]; then
sha256sum "$file" > "$file.sha256"
fi
done

- name: Upload to release
uses: ncipollo/release-action@v1
with:
allowUpdates: true
omitName: true
omitBody: true
omitBodyDuringUpdate: true
prerelease: true
tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "output/images/*-sdcard.img*"

- name: Generate summary
run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card Image Build Complete! 🚀

**Board:** ${{ inputs.board }}
**Target:** ${{ env.TARGET }}
**Bootloader:** ${{ env.BOOTLOADER }}
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}

## Created Images
$(find output/images/ -name "*.img" -o -name "*.qcow2" -o -name "*.raw" | xargs ls -lh 2>/dev/null | sed 's/^/- /' || echo "- No images found")

## Download
The SD card image is available as a workflow artifact above.
EOF
Binary file added board/common/uboot/splash.bmp
Binary file not shown.
4 changes: 4 additions & 0 deletions configs/rpi4_boot_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ BR2_SYSTEM_BIN_SH_NONE=y
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_INFIX_PATH}/board/common/post-image.sh"
# BR2_PACKAGE_BUSYBOX is not set
BR2_PACKAGE_RPI_FIRMWARE=y
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4=y
BR2_PACKAGE_RPI_FIRMWARE_VARIANT_PI4_X=y
BR2_PACKAGE_RPI_FIRMWARE_CONFIG_FILE="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi-4/config.txt"
BR2_PACKAGE_RPI_FIRMWARE_CMDLINE_FILE="${BR2_EXTERNAL_INFIX_PATH}/src/board/raspberry-pi-4/cmdline.txt"
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
Expand All @@ -34,4 +36,6 @@ BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN=y
# GNS3_APPLIANCE is not set
SDCARD_AUX=y
1 change: 1 addition & 0 deletions package/Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ source "$BR2_EXTERNAL_INFIX_PATH/package/rousette/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/nghttp2-asio/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/date-cpp/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/rauc-installation-status/Config.in"
source "$BR2_EXTERNAL_INFIX_PATH/package/bootloader-splashscreen/Config.in"
endmenu
1 change: 1 addition & 0 deletions package/board/raspberry-pi-4/Config.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
config BR2_PACKAGE_RASPBERRY_PI_4
bool "Raspberry Pi 4"
depends on BR2_aarch64
select SDCARD_AUX
select BR2_PACKAGE_FEATURE_WIFI
select BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI
select BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI_WIFI
Expand Down
12 changes: 12 additions & 0 deletions package/bootloader-splashscreen/Config.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
config BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN
bool "bootloader-splashscreen"
help
Install a BMP splash screen image for bootloader.

config BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN_PATH
string "Path to BMP image"
default "$(BR2_EXTERNAL_INFIX_PATH)/board/common/uboot/splash.bmp"
depends on BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN
help
Path to the BMP image file to be used as bootloader splash screen.
The image will be installed to output/images/.
19 changes: 19 additions & 0 deletions package/bootloader-splashscreen/bootloader-splashscreen.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
################################################################################
#
# bootloader-splashscreen
#
################################################################################

BOOTLOADER_SPLASHSCREEN_VERSION = 1.0
BOOTLOADER_SPLASHSCREEN_SOURCE =
BOOTLOADER_SPLASHSCREEN_SITE =

define BOOTLOADER_SPLASHSCREEN_BUILD_CMDS
# Nothing to build
endef

define BOOTLOADER_SPLASHSCREEN_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0644 $(call qstrip,$(BR2_PACKAGE_BOOTLOADER_SPLASHSCREEN_PATH)) $(BINARIES_DIR)/splash.bmp
endef

$(eval $(generic-package))
8 changes: 6 additions & 2 deletions src/board/raspberry-pi-4/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ device_tree=bcm2711-rpi-4-b.dtb
dtoverlay=rpi-env
dtoverlay=infix-key
dtoverlay=vc4-kms-v3d-pi4
dtoverlay=vc4-kms-dsi-7inch
dtoverlay=vc4-kms-dsi-7inch,rotation=180
disable_splash=1
lcd_rotate=2

#ignore_lcd=0

# Prevent console on DSI
console=map:0

# To use an external initramfs file
#initramfs rootfs.cpio.gz
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ set -e
BOARD_DIR=$(dirname "$0")
GENIMAGE_CFG="${BUILD_DIR}/genimage.cfg"
GENIMAGE_TMP="${BUILD_DIR}/genimage.tmp"
#TARGET_DIR="${BR2_EXTERNAL_INFIX_PATH}/output/target"

# Device trees are installed for distro boot (syslinux.conf), but on RPi
# we need them for the SPL, which feeds the TPL (U-Boot) for use instead
# of the (built-in) control DT other platforms use.
find "${TARGET_DIR}/boot" -type f -name '*.dtb' -exec cp '{}' "${BINARIES_DIR}/" \;
#find "${BINARIES_DIR}" -type f -name '*.dtb' -exec cp '{}' "${BINARIES_DIR}/" \;

# We've asked U-Boot previously to build overlays for us: Infix signing
# key and our ixboot scripts. Make sure here they are installed in the
Expand All @@ -26,15 +27,16 @@ for f in "${BINARIES_DIR}"/rpi-firmware/*; do
echo "${FILES}" | grep -q `basename $f` && continue # If already exist it has been added by us.
FILES="${FILES}\t\t\t\"${f#"${BINARIES_DIR}/"}\",\n"
done

FILES="${FILES}\t\t\t\"splash.bmp\",\n"
echo $FILES
KERNEL=$(sed -n 's/^kernel=//p' "${BINARIES_DIR}/rpi-firmware/config.txt")
FILES="${FILES}\t\t\t\"${KERNEL}\""


sed "s|#BOOT_FILES#|${FILES}|" "${BOARD_DIR}/genimage.cfg.in" | \
sed "s|#VERSION#|${RELEASE}|" | \
sed "s|#INFIX_ID#|${INFIX_ID}|" > "${GENIMAGE_CFG}"
sed "s|#INFIX_ID#|${INFIX_ID}|" | \
sed "s|#VERSION#|${RELEASE}|" > "${GENIMAGE_CFG}"


ROOTPATH_TMP=$(mktemp -d)
trap 'rm -rf \"$ROOTPATH_TMP\"' EXIT
Expand Down
9 changes: 9 additions & 0 deletions src/board/raspberry-pi-4/uboot/extras.config
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# CONFIG_MMC_PCI is not set
CONFIG_OF_OVERLAY_LIST="rpi-env infix-key"
# CONFIG_ENV_IS_IN_FAT is not set
CONFIG_CMD_BMP=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_BMP=y
CONFIG_BMP_24BPP=y
#CONFIG_VIDEO_BMP_GZIP=y
CONFIG_VIDEO=y
CONFIG_VIDEO_BMP_RLE8=y
#CONFIG_SILENT_CONSOLE=y
8 changes: 7 additions & 1 deletion src/board/raspberry-pi-4/uboot/rpi-env.dtso
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
bootmenu_delay = "10";
boot_targets = "mmc0";
ethprime = "eth0";
bootcmd = "run ixboot";

stdout = "serial";
stderr = "serial";
stdin = "serial";
splashpos = "m,m";
splashfile = "splash.bmp";
bootcmd = "fatload mmc 0:1 ${loadaddr} ${splashfile}; bmp display ${loadaddr}; run ixboot";

ixpreboot = /incbin/("scripts/ixpreboot.sh");
ixbtn-devmode = "setenv dev_mode yes; echo Enabled";
Expand Down