mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
- Add a board README to explain how to get Infix running - Update mkimage.sh to allow creating images without boot loader Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
696 lines
21 KiB
Bash
Executable File
696 lines
21 KiB
Bash
Executable File
#!/bin/sh
|
|
# Unified SD card image creation script for all boards
|
|
# Consolidates logic from board-specific mkimage.sh scripts
|
|
set -e
|
|
|
|
STANDALONE=""
|
|
if [ -z "$BR2_EXTERNAL_INFIX_PATH" ]; then
|
|
SCRIPT_DIR=$(dirname "$0")
|
|
BR2_EXTERNAL_INFIX_PATH=$(cd "$SCRIPT_DIR/.." && pwd)
|
|
fi
|
|
|
|
usage()
|
|
{
|
|
cat <<EOF
|
|
Create SD card/eMMC image from build artifacts for any supported board.
|
|
|
|
Usage:
|
|
$0 [OPTIONS] <board-name>
|
|
|
|
Options:
|
|
-b boot-dir Path to bootloader build directory (default: same as -r, or O= or output/)
|
|
-B Boot-only image (no rootfs, for bootloader testing)
|
|
-d Download bootloader files from latest-boot release
|
|
-f Force re-download of bootloader even if cached
|
|
-h This help text
|
|
-l List available boards
|
|
-o Override auto-detection of genimage.sh, use host installed version
|
|
-r root-dir Path to rootfs build directory or rootfs.squashfs file (default: O= or output/)
|
|
-t target Image target type: sdcard or emmc (default: sdcard)
|
|
|
|
Arguments:
|
|
board-name Board identifier (must come after options)
|
|
|
|
Description:
|
|
When called from Buildroot (no options), uses environment variables:
|
|
BINARIES_DIR, BUILD_DIR, BR2_EXTERNAL_INFIX_PATH, RELEASE, INFIX_ID
|
|
|
|
When called with -b/-r options, enters standalone mode and combines artifacts
|
|
from separate boot and rootfs sources. Useful for CI or manual image creation.
|
|
|
|
Output:
|
|
Image saved to \$BINARIES_DIR/*-sdcard.img or *-emmc.img
|
|
|
|
Examples:
|
|
# From Buildroot build:
|
|
$0 raspberrypi-rpi64
|
|
|
|
# Standalone with separate boot/rootfs builds:
|
|
$0 -b x-boot -r output raspberrypi-rpi64
|
|
|
|
# Rootfs-only (no separate bootloader build, e.g. EspressoBIN):
|
|
$0 -r x-aarch64 marvell-espressobin
|
|
|
|
# With downloaded rootfs and bootloader:
|
|
$0 -d -r ~/Downloads/rootfs.squashfs friendlyarm-nanopi-r2s
|
|
|
|
# Download bootloader and compose with Linux image in output directory:
|
|
$0 -od bananapi-bpi-r3
|
|
|
|
# Create eMMC image instead of SD card:
|
|
$0 -t emmc bananapi-bpi-r3
|
|
|
|
# Create boot-only image for bootloader testing:
|
|
$0 -B -b build-boot microchip-sama7g54-ek
|
|
|
|
EOF
|
|
}
|
|
|
|
log()
|
|
{
|
|
printf '\033[7m>>> %s\033[0m\n' "$*"
|
|
}
|
|
|
|
err()
|
|
{
|
|
echo "Error: $*" >&2
|
|
}
|
|
|
|
die()
|
|
{
|
|
err "$*"
|
|
exit 1
|
|
}
|
|
|
|
# List all supported boards by scanning for genimage.cfg.in files
|
|
list_boards()
|
|
{
|
|
script_dir=$(dirname "$0")
|
|
board_base=$(cd "$script_dir/../board" 2>/dev/null && pwd)
|
|
|
|
if [ -z "$board_base" ] || [ ! -d "$board_base" ]; then
|
|
echo "Error: Could not find board directory" >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "Available boards:"
|
|
find "$board_base" -name "genimage.cfg.in" -type f 2>/dev/null | \
|
|
grep -v '/common/' | \
|
|
sed 's|.*/board/\([^/]*\)/\([^/]*\)/.*| \2 (\1)|' | \
|
|
sort -u
|
|
}
|
|
|
|
# Run genimage directly (fallback when Buildroot wrapper not available)
|
|
run_genimage()
|
|
{
|
|
genimage_cfg="$1"
|
|
genimage_tmp="${BUILD_DIR}/genimage.tmp"
|
|
rootpath_tmp=$(mktemp -d)
|
|
trap 'rm -rf "$rootpath_tmp"' EXIT
|
|
|
|
rm -rf "$genimage_tmp"
|
|
|
|
genimage \
|
|
--rootpath "$rootpath_tmp" \
|
|
--tmppath "$genimage_tmp" \
|
|
--inputpath "${BINARIES_DIR}" \
|
|
--outputpath "${BINARIES_DIR}" \
|
|
--config "$genimage_cfg"
|
|
|
|
if command -v bmaptool >/dev/null 2>&1; then
|
|
for img in "${BINARIES_DIR}"/*-sdcard*.img "${BINARIES_DIR}"/*-emmc*.img; do
|
|
[ -f "$img" ] || continue
|
|
log "Generating block map for $(basename "$img")..."
|
|
bmaptool create -o "${img}.bmap" "$img"
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Validate board argument and find board directory
|
|
# Sets BOARD and BOARD_DIR globals or exits with error
|
|
validate_board()
|
|
{
|
|
BOARD="$1"
|
|
if [ -z "$BOARD" ]; then
|
|
err "Board name required. Use -h for help."
|
|
return 1
|
|
fi
|
|
|
|
board_underscore=$(echo "$BOARD" | tr '-' '_')
|
|
for arch in arm aarch64 x86_64 riscv64; do
|
|
for variant in "$BOARD" "$board_underscore"; do
|
|
candidate="$BR2_EXTERNAL_INFIX_PATH/board/$arch/$variant"
|
|
if [ -d "$candidate" ]; then
|
|
BOARD_DIR="$candidate"
|
|
return 0
|
|
fi
|
|
done
|
|
done
|
|
|
|
err "Board directory not found for: $BOARD"
|
|
return 1
|
|
}
|
|
|
|
# Find build directory by checking O= or output/
|
|
find_build_dir()
|
|
{
|
|
# Check O= environment variable first
|
|
if [ -n "$O" ] && [ -f "$O/.config" ]; then
|
|
echo "$O"
|
|
return 0
|
|
fi
|
|
|
|
# Check output/ directory
|
|
if [ -f "output/.config" ]; then
|
|
echo "output"
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# Map board name to bootloader identifier
|
|
# Returns bootloader name used in artifact naming
|
|
get_bootloader_name()
|
|
{
|
|
board="$1"
|
|
target="$2"
|
|
case "$board" in
|
|
raspberrypi-rpi2)
|
|
echo "rpi2_boot"
|
|
;;
|
|
raspberrypi-rpi64)
|
|
echo "rpi64_boot"
|
|
;;
|
|
bananapi-bpi-r3)
|
|
if [ "$target" = "emmc" ]; then
|
|
echo "bpi_r3_emmc_boot"
|
|
else
|
|
echo "bpi_r3_sd_boot"
|
|
fi
|
|
;;
|
|
bananapi-bpi-r4)
|
|
if [ "$target" = "emmc" ]; then
|
|
echo "bpi_r4_emmc_boot"
|
|
else
|
|
echo "bpi_r4_sd_boot"
|
|
fi
|
|
;;
|
|
bananapi-bpi-r64)
|
|
if [ "$target" = "emmc" ]; then
|
|
echo "bpi_r64_emmc_boot"
|
|
else
|
|
echo "bpi_r64_sd_boot"
|
|
fi
|
|
;;
|
|
friendlyarm-nanopi-r2s)
|
|
echo "nanopi_r2s_boot"
|
|
;;
|
|
microchip-sama7g54-ek)
|
|
if [ "$target" = "emmc" ]; then
|
|
echo "sama7g54_ek_emmc_boot"
|
|
else
|
|
echo "sama7g54_ek_sd_boot"
|
|
fi
|
|
;;
|
|
*)
|
|
err "Unknown bootloader for board: $board"
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Download and extract bootloader from latest-boot release
|
|
# Downloads to dl/bootloader/ cache and extracts to temporary build directory
|
|
# Returns the temporary directory path in SDCARD_TEMP_DIR variable
|
|
download_bootloader()
|
|
{
|
|
board="$1"
|
|
build_dir="$2"
|
|
target="$3"
|
|
|
|
bootloader=$(get_bootloader_name "$board" "$target") || return 1
|
|
|
|
if ! command -v gh >/dev/null 2>&1; then
|
|
die "gh CLI not found. Install it or build bootloader locally."
|
|
fi
|
|
|
|
# Set up download cache directory
|
|
dl_dir="${BR2_EXTERNAL_INFIX_PATH}/dl/bootloader"
|
|
mkdir -p "$dl_dir"
|
|
|
|
# Convert underscores to dashes for filename pattern matching
|
|
bootloader_pattern=$(echo "$bootloader" | tr '_' '-')
|
|
|
|
# Find or download bootloader tarball
|
|
tarball=$(ls "$dl_dir"/${bootloader_pattern}*.tar.gz 2>/dev/null | head -n1)
|
|
|
|
if [ -z "$tarball" ] || [ -n "$FORCE_DOWNLOAD" ]; then
|
|
if [ -n "$FORCE_DOWNLOAD" ] && [ -n "$tarball" ]; then
|
|
log "Force re-downloading bootloader..."
|
|
rm -f "$tarball" "$tarball.sha256"
|
|
else
|
|
log "Downloading bootloader $bootloader from latest-boot release..."
|
|
fi
|
|
|
|
if ! gh release download latest-boot \
|
|
--repo kernelkit/infix \
|
|
--pattern "*${bootloader_pattern}*.tar.gz" \
|
|
--dir "$dl_dir"; then
|
|
die "Failed downloading bootloader from latest-boot release. Check gh authentication and network connectivity."
|
|
fi
|
|
|
|
tarball=$(ls "$dl_dir"/${bootloader_pattern}*.tar.gz 2>/dev/null | head -n1)
|
|
[ -n "$tarball" ] || die "Downloaded tarball not found in $dl_dir"
|
|
else
|
|
log "Using cached bootloader: $(basename "$tarball")"
|
|
fi
|
|
|
|
# Create temporary directory for SD card composition
|
|
SDCARD_TEMP_DIR="${build_dir}/sdcard-${board}-$$"
|
|
mkdir -p "$SDCARD_TEMP_DIR"
|
|
|
|
log "Extracting bootloader to $SDCARD_TEMP_DIR..."
|
|
tar -xzf "$tarball" --strip-components=1 -C "$SDCARD_TEMP_DIR/"
|
|
|
|
log "Bootloader ready in temporary directory"
|
|
}
|
|
|
|
# Build EN8811H firmware partition image as an ext4 filesystem containing
|
|
# EthMD32.dm.bin and EthMD32.DSP.bin. Returns 0 when created, 1 when source
|
|
# files are missing.
|
|
prepare_en8811h_fw_image()
|
|
{
|
|
src_dir="$1"
|
|
out_img="$2"
|
|
dm_fw="${src_dir}/EthMD32.dm.bin"
|
|
dsp_fw="${src_dir}/EthMD32.DSP.bin"
|
|
fw_staging=""
|
|
|
|
[ -f "$dm_fw" ] && [ -f "$dsp_fw" ] || return 1
|
|
|
|
fw_staging=$(mktemp -d)
|
|
cp "$dm_fw" "$fw_staging/EthMD32.dm.bin"
|
|
cp "$dsp_fw" "$fw_staging/EthMD32.DSP.bin"
|
|
|
|
rm -f "$out_img"
|
|
truncate -s 2M "$out_img"
|
|
|
|
if command -v mke2fs >/dev/null 2>&1; then
|
|
mke2fs -q -t ext4 -L en8811h_fw -d "$fw_staging" "$out_img"
|
|
elif command -v mkfs.ext4 >/dev/null 2>&1; then
|
|
mkfs.ext4 -q -L en8811h_fw -d "$fw_staging" "$out_img"
|
|
else
|
|
rm -rf "$fw_staging"
|
|
die "mke2fs/mkfs.ext4 not found, cannot create en8811h-fw.bin"
|
|
fi
|
|
|
|
rm -rf "$fw_staging"
|
|
return 0
|
|
}
|
|
|
|
maybe_prepare_en8811h_fw_image()
|
|
{
|
|
out_img="${BINARIES_DIR}/en8811h-fw.bin"
|
|
|
|
[ -f "$out_img" ] && return 0
|
|
|
|
prepare_en8811h_fw_image "${ROOT_DIR}/images/airoha" "$out_img" || \
|
|
prepare_en8811h_fw_image "${ROOT_DIR}/airoha" "$out_img" || \
|
|
prepare_en8811h_fw_image "${BINARIES_DIR}/airoha" "$out_img" || return 0
|
|
}
|
|
|
|
# Discover boot files for Raspberry Pi boot partition
|
|
# Scans rpi-firmware directory and builds file list for genimage
|
|
discover_rpi_boot_files()
|
|
{
|
|
binaries_dir="$1"
|
|
files=""
|
|
|
|
# Move any .dtbo overlays to proper location
|
|
find "${binaries_dir}" -type f -name '*.dtbo' ! -path "${binaries_dir}/rpi-firmware/overlays/*" -exec \
|
|
mv '{}' "${binaries_dir}/rpi-firmware/overlays/" \; 2>/dev/null || true
|
|
|
|
# Scan rpi-firmware directory for boot files
|
|
for f in "${binaries_dir}"/rpi-firmware/*; do
|
|
[ -e "$f" ] || continue
|
|
case "$f" in
|
|
*~ | *.bak)
|
|
continue
|
|
;;
|
|
esac
|
|
# Skip if already in list
|
|
echo "${files}" | grep -q "$(basename "$f")" && continue
|
|
files="${files}\t\t\t\"${f#"${binaries_dir}/"}\",\n"
|
|
done
|
|
|
|
# Add splash screen if it exists
|
|
if [ -f "${binaries_dir}/splash.bmp" ]; then
|
|
files="${files}\t\t\t\"splash.bmp\",\n"
|
|
fi
|
|
|
|
# Add kernel (extract name from config.txt)
|
|
if [ -f "${binaries_dir}/rpi-firmware/config.txt" ]; then
|
|
kernel=$(sed -n 's/^kernel=//p' "${binaries_dir}/rpi-firmware/config.txt")
|
|
files="${files}\t\t\t\"${kernel}\""
|
|
fi
|
|
|
|
echo "$files"
|
|
}
|
|
|
|
# Filter genimage.cfg.in for boot-only image
|
|
# Removes rootfs-related blocks: image cfg.ext4, image var.ext4,
|
|
# and partitions: aux, primary, secondary, cfg, var
|
|
filter_bootonly_genimage()
|
|
{
|
|
awk '
|
|
BEGIN { skip=0; depth=0 }
|
|
/^image cfg\.ext4/ || /^image var\.ext4/ {
|
|
skip=1; depth=1; next
|
|
}
|
|
/^[[:space:]]*partition (aux|primary|secondary|cfg|var)[[:space:]]*\{/ {
|
|
skip=1; depth=1; next
|
|
}
|
|
skip==1 {
|
|
# Count braces on this line to track nesting depth
|
|
n = gsub(/{/, "{")
|
|
m = gsub(/}/, "}")
|
|
depth = depth + n - m
|
|
if (depth <= 0) { skip=0; depth=0 }
|
|
next
|
|
}
|
|
{ print }
|
|
'
|
|
}
|
|
|
|
while getopts "hldfoBb:r:t:" opt; do
|
|
case $opt in
|
|
b)
|
|
BOOT_DIR="$OPTARG"
|
|
STANDALONE=1
|
|
;;
|
|
B)
|
|
BOOT_ONLY=1
|
|
STANDALONE=1
|
|
;;
|
|
d)
|
|
DOWNLOAD_BOOT=1
|
|
STANDALONE=1
|
|
;;
|
|
f)
|
|
FORCE_DOWNLOAD=1
|
|
;;
|
|
h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
l)
|
|
list_boards
|
|
exit 0
|
|
;;
|
|
o)
|
|
OVERRIDE=1
|
|
;;
|
|
r)
|
|
ROOT_DIR="$OPTARG"
|
|
STANDALONE=1
|
|
;;
|
|
t)
|
|
TARGET="$OPTARG"
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND - 1))
|
|
|
|
if ! validate_board "$1"; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
# Validate and set default target
|
|
: "${TARGET:=sdcard}"
|
|
case "$TARGET" in
|
|
sd|sdcard)
|
|
TARGET="sdcard"
|
|
;;
|
|
emmc)
|
|
TARGET="emmc"
|
|
;;
|
|
*)
|
|
err "Invalid target: $TARGET. Must be 'sdcard' or 'emmc'"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# Standalone mode: set up environment from build directories
|
|
if [ -n "$STANDALONE" ]; then
|
|
# In download mode without explicit dirs, default to same location for both
|
|
if [ -n "$DOWNLOAD_BOOT" ]; then
|
|
default_dir=$(find_build_dir) || die "Could not find build directory. Set O= or use -b/-r option"
|
|
: "${BOOT_DIR:=$default_dir}"
|
|
: "${ROOT_DIR:=$default_dir}"
|
|
elif [ -n "$BOOT_ONLY" ]; then
|
|
# Boot-only mode: only need bootloader directory
|
|
if [ -z "$BOOT_DIR" ]; then
|
|
BOOT_DIR=$(find_build_dir) || die "Could not find boot directory. Use -b option"
|
|
fi
|
|
else
|
|
if [ -z "$ROOT_DIR" ]; then
|
|
ROOT_DIR=$(find_build_dir) || die "Could not find rootfs directory. Set O= or use -r option"
|
|
fi
|
|
|
|
if [ -z "$BOOT_DIR" ]; then
|
|
# For boards without a separate bootloader build (e.g. EspressoBIN,
|
|
# where U-Boot lives in SPI NOR), -r alone is sufficient: default
|
|
# the boot directory to the rootfs directory.
|
|
if [ -n "$ROOT_DIR" ]; then
|
|
BOOT_DIR="$ROOT_DIR"
|
|
else
|
|
BOOT_DIR=$(find_build_dir) || die "Could not find boot directory. Use -b option"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Set up environment variables, some required by genimage.sh
|
|
export BINARIES_DIR="$BOOT_DIR/images"
|
|
export BUILD_DIR="$BOOT_DIR/build"
|
|
export BR2_EXTERNAL_INFIX_PATH
|
|
export RELEASE="${RELEASE:-""}"
|
|
export INFIX_ID="${INFIX_ID:-"infix"}"
|
|
|
|
# Add host tools to PATH (for genimage, bmaptool, etc.)
|
|
for dir in "$BOOT_DIR" "$ROOT_DIR"; do
|
|
[ -n "$dir" ] || continue
|
|
if [ -d "$dir/host/bin" ]; then
|
|
export PATH="$dir/host/bin:$PATH"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Copy rootfs and partition images to BINARIES_DIR (skip in boot-only mode)
|
|
mkdir -p "$BINARIES_DIR"
|
|
|
|
if [ -z "$BOOT_ONLY" ]; then
|
|
# Normalize paths for comparison
|
|
boot_images=$(cd "$BOOT_DIR" && pwd)/images
|
|
root_images=""
|
|
|
|
if [ -f "$ROOT_DIR" ]; then
|
|
# Direct path to rootfs.squashfs file
|
|
log "Copying rootfs from $ROOT_DIR to $BINARIES_DIR/rootfs.squashfs"
|
|
cp "$ROOT_DIR" "$BINARIES_DIR/rootfs.squashfs"
|
|
elif [ -f "$ROOT_DIR/images/rootfs.squashfs" ]; then
|
|
root_images=$(cd "$ROOT_DIR" && pwd)/images
|
|
# Only copy if different directories
|
|
if [ "$boot_images" != "$root_images" ]; then
|
|
# Build directory with images/ - copy rootfs and partition images
|
|
log "Copying artifacts from $ROOT_DIR/images/ to $BINARIES_DIR/"
|
|
cp "$ROOT_DIR/images/rootfs.squashfs" "$BINARIES_DIR/"
|
|
# Copy partition images and rootfs variants if they exist
|
|
for img in aux.ext4 cfg.ext4 var.ext4 rootfs.ext2; do
|
|
if [ -f "$ROOT_DIR/images/$img" ]; then
|
|
cp "$ROOT_DIR/images/$img" "$BINARIES_DIR/"
|
|
fi
|
|
done
|
|
else
|
|
log "Rootfs already in place at $BINARIES_DIR/"
|
|
fi
|
|
elif [ -f "$ROOT_DIR/rootfs.squashfs" ]; then
|
|
# Directory directly containing rootfs.squashfs
|
|
log "Copying rootfs from $ROOT_DIR/rootfs.squashfs"
|
|
cp "$ROOT_DIR/rootfs.squashfs" "$BINARIES_DIR/"
|
|
# Copy partition images and rootfs variants if they exist
|
|
for img in aux.ext4 cfg.ext4 var.ext4 rootfs.ext2; do
|
|
if [ -f "$ROOT_DIR/$img" ]; then
|
|
cp "$ROOT_DIR/$img" "$BINARIES_DIR/"
|
|
fi
|
|
done
|
|
else
|
|
die "Could not find rootfs.squashfs in $ROOT_DIR"
|
|
fi
|
|
fi
|
|
else
|
|
# Export for Buildroot genimage.sh wrapper
|
|
export BINARIES_DIR
|
|
export BUILD_DIR
|
|
fi
|
|
|
|
# Validate required environment variables
|
|
: "${BINARIES_DIR:?'not set'}"
|
|
: "${BUILD_DIR:?'not set'}"
|
|
: "${BR2_EXTERNAL_INFIX_PATH:?'not set'}"
|
|
|
|
# Set defaults for optional variables
|
|
: "${RELEASE:=""}"
|
|
: "${INFIX_ID:="infix"}"
|
|
|
|
# Download bootloader if requested
|
|
if [ -n "$DOWNLOAD_BOOT" ]; then
|
|
# Save original output location
|
|
ORIGINAL_BINARIES_DIR="$BINARIES_DIR"
|
|
|
|
download_bootloader "$BOARD" "$BUILD_DIR" "$TARGET"
|
|
|
|
# Now use the temporary directory for composition
|
|
BINARIES_DIR="$SDCARD_TEMP_DIR"
|
|
|
|
# Link rootfs and partition images to temp directory (skip in boot-only mode)
|
|
if [ -z "$BOOT_ONLY" ]; then
|
|
log "Linking rootfs files to $BINARIES_DIR..."
|
|
if [ -f "$ROOT_DIR" ]; then
|
|
# Direct path to rootfs.squashfs file
|
|
ln -sf "$(realpath "$ROOT_DIR")" "$BINARIES_DIR/rootfs.squashfs"
|
|
elif [ -f "$ROOT_DIR/images/rootfs.squashfs" ]; then
|
|
ln -sf "$(realpath "$ROOT_DIR/images/rootfs.squashfs")" "$BINARIES_DIR/rootfs.squashfs"
|
|
# Link partition images and rootfs variants if they exist
|
|
for img in aux.ext4 cfg.ext4 var.ext4 rootfs.ext2; do
|
|
if [ -f "$ROOT_DIR/images/$img" ]; then
|
|
ln -sf "$(realpath "$ROOT_DIR/images/$img")" "$BINARIES_DIR/$img"
|
|
fi
|
|
done
|
|
elif [ -f "$ROOT_DIR/rootfs.squashfs" ]; then
|
|
ln -sf "$(realpath "$ROOT_DIR/rootfs.squashfs")" "$BINARIES_DIR/rootfs.squashfs"
|
|
# Link partition images and rootfs variants if they exist
|
|
for img in aux.ext4 cfg.ext4 var.ext4 rootfs.ext2; do
|
|
if [ -f "$ROOT_DIR/$img" ]; then
|
|
ln -sf "$(realpath "$ROOT_DIR/$img")" "$BINARIES_DIR/$img"
|
|
fi
|
|
done
|
|
else
|
|
die "Could not find rootfs.squashfs in $ROOT_DIR"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$BOARD" = "bananapi-bpi-r3" ]; then
|
|
maybe_prepare_en8811h_fw_image
|
|
[ -f "${BINARIES_DIR}/en8811h-fw.bin" ] || die "Missing EN8811H firmware image: ${BINARIES_DIR}/en8811h-fw.bin"
|
|
fi
|
|
|
|
# Template expansion
|
|
log "Generating genimage configuration for $BOARD..."
|
|
|
|
GENIMAGE_CFG="${BUILD_DIR}/genimage.cfg"
|
|
GENIMAGE_TEMPLATE="$BOARD_DIR/genimage.cfg.in"
|
|
[ -f "$GENIMAGE_TEMPLATE" ] || die "genimage.cfg.in not found in $BOARD_DIR"
|
|
|
|
# Check if board needs special boot file discovery (Raspberry Pi)
|
|
if { [ "$BOARD" = "raspberrypi-rpi2" ] || [ "$BOARD" = "raspberrypi-rpi64" ]; } && grep -q '#BOOT_FILES#' "$GENIMAGE_TEMPLATE"; then
|
|
log "Discovering Raspberry Pi boot files..."
|
|
BOOT_FILES=$(discover_rpi_boot_files "$BINARIES_DIR")
|
|
# Create temp file with interpreted escape sequences
|
|
bootfiles_tmp="${BUILD_DIR}/bootfiles.tmp"
|
|
printf '%b' "$BOOT_FILES" > "$bootfiles_tmp"
|
|
# Use sed to insert content and delete placeholder
|
|
sed -e "/#BOOT_FILES#/r $bootfiles_tmp" -e "/#BOOT_FILES#/d" "$GENIMAGE_TEMPLATE" > "${GENIMAGE_CFG}.tmp"
|
|
rm -f "$bootfiles_tmp"
|
|
GENIMAGE_TEMPLATE="${GENIMAGE_CFG}.tmp"
|
|
fi
|
|
|
|
# Filter for boot-only mode if requested
|
|
if [ -n "$BOOT_ONLY" ]; then
|
|
log "Filtering genimage config for boot-only image..."
|
|
filter_bootonly_genimage < "$GENIMAGE_TEMPLATE" > "${GENIMAGE_CFG}.filtered"
|
|
GENIMAGE_TEMPLATE="${GENIMAGE_CFG}.filtered"
|
|
fi
|
|
|
|
# Expand template variables
|
|
# For boot-only mode, append "-boot" to the target name in the image filename
|
|
if [ -n "$BOOT_ONLY" ]; then
|
|
sed "s|#VERSION#|${RELEASE}|" "$GENIMAGE_TEMPLATE" | \
|
|
sed "s|#INFIX_ID#|${INFIX_ID}|" | \
|
|
sed "s|#TARGET#|${TARGET}|" | \
|
|
sed "s|-${TARGET}\.img|-${TARGET}-boot.img|" > "$GENIMAGE_CFG"
|
|
else
|
|
sed "s|#VERSION#|${RELEASE}|" "$GENIMAGE_TEMPLATE" | \
|
|
sed "s|#INFIX_ID#|${INFIX_ID}|" | \
|
|
sed "s|#TARGET#|${TARGET}|" > "$GENIMAGE_CFG"
|
|
fi
|
|
|
|
# Clean up temp files if created
|
|
#rm -f "${GENIMAGE_CFG}.tmp" "${GENIMAGE_CFG}.filtered"
|
|
|
|
# Find and set up for calling genimage/genimage.sh
|
|
if [ -z "$BR2_CONFIG" ]; then
|
|
BR2_CONFIG="/dev/null"
|
|
if [ -f "${BUILD_DIR}/../.config" ]; then
|
|
BR2_CONFIG="$(realpath "${BUILD_DIR}/../.config")"
|
|
fi
|
|
export BR2_CONFIG
|
|
|
|
if [ -f "$BR2_EXTERNAL_INFIX_PATH/../buildroot/support/scripts/genimage.sh" ]; then
|
|
GENIMAGE_WRAPPER="$(realpath "$BR2_EXTERNAL_INFIX_PATH/../buildroot/support/scripts/genimage.sh")"
|
|
fi
|
|
else
|
|
GENIMAGE_WRAPPER="support/scripts/genimage.sh"
|
|
fi
|
|
|
|
if [ -z "$OVERRIDE" ] && command -v "$GENIMAGE_WRAPPER" >/dev/null 2>&1; then
|
|
log "Creating $TARGET image using Buildroot $(basename "$GENIMAGE_WRAPPER") ..."
|
|
"$GENIMAGE_WRAPPER" -c "$GENIMAGE_CFG"
|
|
else
|
|
log "Creating $TARGET image ..."
|
|
run_genimage "$GENIMAGE_CFG"
|
|
fi
|
|
|
|
# Post-processing: move images and cleanup if using download mode
|
|
if [ -n "$DOWNLOAD_BOOT" ]; then
|
|
log "Moving $TARGET images to $ORIGINAL_BINARIES_DIR..."
|
|
mkdir -p "$ORIGINAL_BINARIES_DIR"
|
|
|
|
for img in "${BINARIES_DIR}"/*-sdcard*.img* "${BINARIES_DIR}"/*-emmc*.img*; do
|
|
if [ -f "$img" ]; then
|
|
mv "$img" "$ORIGINAL_BINARIES_DIR/"
|
|
log " $(basename "$img")"
|
|
fi
|
|
done
|
|
|
|
log "Cleaning up temporary directory..."
|
|
rm -rf "$SDCARD_TEMP_DIR"
|
|
|
|
# Update BINARIES_DIR for final output message
|
|
BINARIES_DIR="$ORIGINAL_BINARIES_DIR"
|
|
fi
|
|
|
|
if [ -n "$BOOT_ONLY" ]; then
|
|
log "$TARGET boot-only image created successfully:"
|
|
else
|
|
log "$TARGET image created successfully:"
|
|
fi
|
|
for img in "${BINARIES_DIR}"/*-sdcard*.img* "${BINARIES_DIR}"/*-emmc*.img*; do
|
|
if [ -f "$img" ]; then
|
|
if [ -n "$STANDALONE" ]; then
|
|
# Show relative path in standalone mode
|
|
rel_path=$(realpath --relative-to="$PWD" "$img" 2>/dev/null || echo "$img")
|
|
echo " $rel_path"
|
|
else
|
|
echo " $(basename "$img")"
|
|
fi
|
|
fi
|
|
done
|