#!/usr/bin/env bash # # SPDX-License-Identifier: GPL-2.0 # # Copyright (c) 2026 AMLOGIC # # U-Boot build script for AMLbian # This script builds U-Boot for different Amlogic chipsets set -e # Get script directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" AMLBIAN_DIR="$(dirname "${SCRIPT_DIR}")" # Source common functions if [[ -f "${AMLBIAN_DIR}/lib/function-common.sh" ]]; then source "${AMLBIAN_DIR}/lib/function-common.sh" fi # ============================================================================== # Section 1: Help Information # ============================================================================== function show_help() { cat << EOF Usage: $(basename "$0") [OPTIONS] Build U-Boot for Amlogic boards Options: --uboot-version VERSION U-Boot version (2023, 2025) --board BOARD Board name (s6-bq201, a9-by401) --source-dir PATH Local U-Boot source directory --output-dir PATH Output directory for build artifacts --clean Clean before build --help Show this help message Examples: $(basename "$0") --uboot-version 2023 --board s6-bq201 $(basename "$0") --source-dir /path/to/uboot --clean EOF } # ============================================================================== # Section 2: Default Configuration # ============================================================================== UBOOT_VERSION="${UBOOT_VERSION:-2023}" BOARD="${BOARD:-s6-bq201}" # SOURCE_DIR="${LOCAL_UBOOT_PATH:-${AMLBIAN_DIR}/../aml-comp/uboot/bl33/v2023}" SOURCE_DIR="${LOCAL_UBOOT_PATH:-${AMLBIAN_DIR}/../../aml-comp/uboot}" #OUTPUT_DIR="${AMLBIAN_DIR}/../../aml-comp/uboot/output" OUTPUT_DIR="${AMLBIAN_DIR}/../output/uboot" CLEAN_BUILD="no" # ============================================================================== # Section 3: Parse Arguments # ============================================================================== while [[ $# -gt 0 ]]; do case "$1" in --uboot-version) UBOOT_VERSION="$2" shift 2 ;; --board) BOARD="$2" shift 2 ;; --source-dir) SOURCE_DIR="$2" shift 2 ;; --output-dir) OUTPUT_DIR="$2" shift 2 ;; --clean) CLEAN_BUILD="yes" shift ;; --help) show_help exit 0 ;; *) echo "Unknown option: $1" show_help exit 1 ;; esac done # ============================================================================== # Section 4: Build U-Boot # ============================================================================== function package_uboot_deb_amlbian_main() { local aml_comp_uboot_path="${1}" local bootconfig="${2}" local uboot_version="${3}" display_alert "U-Boot" "DEB Packaging ... ..." # Check if U-Boot directory exists if [[ -z "${aml_comp_uboot_path}" || ! -d "${aml_comp_uboot_path}" ]]; then display_alert "PACKAGE-UBOOT" "U-Boot source directory not found: ${aml_comp_uboot_path}" display_alert "PACKAGE-UBOOT" "Skipping U-Boot DEB packaging" return 0 fi local build_dir="${aml_comp_uboot_path}/build" if [[ ! -d "${build_dir}" ]]; then display_alert "error" "PACKAGE-UBOOT" "U-Boot build directory not found: ${build_dir}" return 1 fi # Check for U-Boot artifacts local uboot_binary="${build_dir}/u-boot.bin.signed" if [[ ! -f "${uboot_binary}" ]]; then display_alert "PACKAGE-UBOOT" "U-Boot binary not found: ${uboot_binary}" display_alert "PACKAGE-UBOOT" "Cannot create DEB package without U-Boot binary" return 0 fi display_alert "PACKAGE-UBOOT" "Creating U-Boot DEB package...${SRC}" display_alert "PACKAGE-UBOOT" " Source: ${aml_comp_uboot_path}" display_alert "PACKAGE-UBOOT" " Bootconfig: ${bootconfig}" display_alert "PACKAGE-UBOOT" " Version: ${uboot_version}" # If BUILD_REPOSITORY_COMMIT is not provided, try to derive it from # the aml-comp U-Boot branch git tree at ${aml_comp_uboot_path}/bl33/${uboot_version} if [[ -z "${BUILD_REPOSITORY_COMMIT:-}" ]]; then git_dir_candidate="${aml_comp_uboot_path}/bl33/${uboot_version}" if command -v git >/dev/null 2>&1 && [[ -d "${git_dir_candidate}" ]]; then if git -C "${git_dir_candidate}" rev-parse --git-dir >/dev/null 2>&1; then BUILD_REPOSITORY_COMMIT="$(git -C "${git_dir_candidate}" rev-parse --short=7 HEAD 2>/dev/null || true)" export BUILD_REPOSITORY_COMMIT display_alert "PACKAGE-UBOOT" "Derived BUILD_REPOSITORY_COMMIT=${BUILD_REPOSITORY_COMMIT} from ${git_dir_candidate}" fi fi fi # ==================================================================== # Step 1: Prepare DEB Package Structure # ==================================================================== local package_name="linux-u-boot-${BOARD}-amlbian" local package_version="${BUILD_REPOSITORY_COMMIT:-0}" local package_arch="arm64" # Create temporary package directory local temp_dir="${SRC}/output/temp-uboot-deb" rm -rf "${temp_dir}" mkdir -p "${temp_dir}/${package_name}" # Create DEBIAN control directory local control_dir="${temp_dir}/${package_name}/DEBIAN" mkdir -p "${control_dir}" # ==================================================================== # Step 2: Create Control File # ==================================================================== cat > "${control_dir}/control" << EOF Package: ${package_name} Version: ${package_version} Architecture: ${package_arch} Maintainer: Amlbian Build System Installed-Size: $(du -sk "${build_dir}" | cut -f1) Section: kernel Priority: optional Provides: u-boot, u-boot-${BOARD} Conflicts: linux-u-boot-${BOARD}-armbian Description: Custom U-Boot for ${BOARD} (Amlbian) This package contains a custom U-Boot bootloader built from local sources for ${BOARD}. It includes signed binaries ready for Amlogic devices. . Features: - Custom U-Boot ${uboot_version} - Signed binaries for secure boot - Optimized for ${BOARD} (${bootconfig}) - Built with Amlbian build system EOF # ==================================================================== # Step 3: Copy U-Boot Files # ==================================================================== local install_dir="${temp_dir}/${package_name}/usr/lib/${package_name}" mkdir -p "${install_dir}" # Copy U-Boot binaries cp "${build_dir}/u-boot.bin.signed" "${install_dir}/" cp "${build_dir}/u-boot.bin.sd.bin.signed" "${install_dir}/" 2>/dev/null || true cp "${build_dir}/u-boot.bin.usb.signed" "${install_dir}/" 2>/dev/null || true # Copy any other U-Boot artifacts find "${build_dir}" -name "*.bin" -o -name "*.img" -type f 2>/dev/null | while read file; do cp "${file}" "${install_dir}/" 2>/dev/null || true done # Create postinst script cat > "${control_dir}/postinst" << EOF #!/bin/bash set -e echo "[AMLBIAN] Installing custom U-Boot for ${BOARD}..." if [ "\$1" = "configure" ]; then UBOOT="/usr/lib/${package_name}/u-boot.bin.signed" echo " U-Boot binaries installed to /usr/lib/${package_name}/" # Check U-Boot image if [ ! -f "\${UBOOT}" ]; then echo "[AMLBIAN] ERROR: U-Boot image not found:" echo " \${UBOOT}" exit 1 fi # Check eMMC boot partitions. # During rootfs build these devices normally do not exist, # so skip the actual U-Boot update. if [ ! -b /dev/mmcblk0boot0 ] || [ ! -b /dev/mmcblk0boot1 ]; then echo "[AMLBIAN] eMMC boot partitions not found." echo "[AMLBIAN] Skipping U-Boot device update." echo "[AMLBIAN] U-Boot image installed to:" echo " \${UBOOT}" exit 0 fi echo " U-Boot image: \${UBOOT}" echo " Size: \$(stat -c %s "\${UBOOT}") bytes" echo "[AMLBIAN] Enabling eMMC boot partition write access..." echo 0 > /sys/class/block/mmcblk0boot0/force_ro echo 0 > /sys/class/block/mmcblk0boot1/force_ro echo "[AMLBIAN] Writing U-Boot to /dev/mmcblk0boot0..." dd if="\${UBOOT}" \ of=/dev/mmcblk0boot0 \ bs=512 \ seek=1 \ conv=fsync \ status=progress echo "[AMLBIAN] Writing U-Boot to /dev/mmcblk0boot1..." dd if="\${UBOOT}" \ of=/dev/mmcblk0boot1 \ bs=512 \ seek=1 \ conv=fsync \ status=progress sync echo "[AMLBIAN] U-Boot update completed successfully." fi exit 0 EOF chmod 755 "${control_dir}/postinst" # Create prerm script cat > "${control_dir}/prerm" << 'EOF' #!/bin/bash set -e echo "[AMLBIAN] Removing custom U-Boot for ${BOARD}..." if [ "$1" = "remove" ]; then echo " Removing U-Boot binaries..." fi exit 0 EOF chmod 755 "${control_dir}/prerm" # ==================================================================== # Step 4: Build DEB Package # ==================================================================== local output_dir="${SRC}/output" mkdir -p "${output_dir}" display_alert "PACKAGE-UBOOT" "Building DEB package...${output_dir}" # Change to temp directory and build package cd "${temp_dir}" || { display_alert "PACKAGE-UBOOT" "Failed to change to temp directory" "error" return 1 } dpkg-deb --build "${package_name}" 2>&1 | while read line; do display_alert "PACKAGE-UBOOT" "dpkg-deb: ${line}" done local exit_code=${PIPESTATUS[0]} cd - > /dev/null if [[ ${exit_code} -ne 0 ]]; then display_alert "PACKAGE-UBOOT" "Failed to build DEB package" "error" rm -rf "${temp_dir}" return ${exit_code} fi # Move package to output directory local deb_file="${package_name}_${package_version}_${package_arch}.deb" mv "${temp_dir}/${package_name}.deb" "${output_dir}/${deb_file}" # Clean up rm -rf "${temp_dir}" # ==================================================================== # Step 5: Verify Package # ==================================================================== if [[ -f "${output_dir}/${deb_file}" ]]; then display_alert "success" "PACKAGE-UBOOT" "DEB package created: ${deb_file}" display_alert "PACKAGE-UBOOT" "Size: $(du -h "${output_dir}/${deb_file}" | cut -f1)" # Show package info display_alert "PACKAGE-UBOOT" "Package contents:" dpkg-deb -c "${output_dir}/${deb_file}" 2>/dev/null | head -5 | while read line; do display_alert "PACKAGE-UBOOT" " ${line}" done # Create package manifest create_package_manifest "${output_dir}" "${deb_file}" "U-Boot" return 0 else display_alert "error" "PACKAGE-UBOOT" "DEB package not created" return 1 fi } # ============================================================================== # Custom U-Boot Compilation # ============================================================================== function compile_uboot_custom() { echo "enter compile_uboot_custom" local aml_comp_uboot_path="${1}" local uboot_version="${2}" local force_compile="${3}" local exit_code=0 local original_dir="$(pwd)" display_alert "UBOOT-CUSTOM Executing custom U-Boot build for version: ${2} on ${1} force ${3}" "info" local src_dir="${aml_comp_uboot_path}" local hdmionly_conf="" if [ ${HDMIONLY} = "yes" ];then #hdmionly_conf="${AMLBIAN_DIR}/patches/uboot/hdmionly_${UBOOT_VERSION}.cfg" display_alert "export BOARD_COMPILE_HDMITX_ONLY as true while HDMIONLY=yes" "info" export BOARD_COMPILE_HDMITX_ONLY=true fi ### UBOOT_VERSION = 2023/2025 display_alert "UBOOT-CUSTOM ${UBOOT_VERSION} $UBOOT_VENDOR_DIR ${UBOOT_MACHINE} $UBOOT_DEFCONFIG_DIR" "debug" display_alert "UBOOT-CUSTOM" "U-Boot v${UBOOT_VERSION} build (DOING)" "info" if [ -f $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak ];then display_alert "exist $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak rebuild or code dirty..........." "debug" else mv $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak display_alert "-f $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak" "debug" KCONFIG_CONFIG=${UBOOT_DEFCONFIG_DIR}/${UBOOT_MACHINE}_defconfig ${AMLBIAN_DIR}/scripts/merge_config.sh -m -r \ ${UBOOT_DEFCONFIG_DIR}/${UBOOT_MACHINE}_defconfig.bak \ ${AMLBIAN_DIR}/patches/uboot/debian_config_${UBOOT_VERSION}.cfg ${hdmionly_conf} fi if [ ! -f $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig ];then display_alert "Error: NO $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig" "error" exit 1 else if grep -q "CONFIG_BUILD_DEBIAN_SYSTEM" "$UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig"; then display_alert "merge success......." "info" else display_alert "Error: merge failed, NO CONFIG_BUILD_DEBIAN_SYSTEM, $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig" "error" exit 1 fi fi cd $UBOOT_VENDOR_DIR if [[ -x "./mk" ]]; then display_alert "UBOOT-CUSTOM" "Running: ./mk ${UBOOT_MACHINE}" "info" ./mk ${UBOOT_MACHINE} exit_code=$? fi # it may be keeping in your debugging if [ -f $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak ];then if [ $DEBUG = "yes" ];then display_alert "UBOOT-CUSTOM keep ${AMLBIAN_DIR}/../output/${UBOOT_MACHINE}_defconfig.bak for debug" "debug" cp $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak ${AMLBIAN_DIR}/../output/ fi mv $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig.bak $UBOOT_DEFCONFIG_DIR/${UBOOT_MACHINE}_defconfig fi # Return to original directory cd "${original_dir}" display_alert "UBOOT-CUSTOM" "Custom U-Boot build for v${UBOOT_VERSION} done" "info" if [[ ${exit_code} -ne 0 ]]; then display_alert "UBOOT-CUSTOM" "U-Boot v{UBOOT_VERSION} build failed (exit code: ${exit_code})" "error" return ${exit_code} fi display_alert "UBOOT-CUSTOM" "U-Boot v${UBOOT_VERSION} build completed successfully" "info" return ${exit_code} } function amlbian_build_uboot() { if ! is_unit_enabled "uboot"; then echo "[SKIP] uboot" return fi display_alert "AMLOGIC TODO: Building U-Boot ${UBOOT_VERSION}" "${BOARD}" "info" display_alert "AMLOGIC TODO: Source directory" "${SOURCE_DIR}" "info" display_alert "AMLOGIC TODO: Output directory" "${OUTPUT_DIR}" "info" # Check if source directory exists if [[ ! -d "${SOURCE_DIR}" ]]; then display_alert "AMLOGIC TODO: U-Boot source not found" "${SOURCE_DIR}" "err" return 1 fi # Create output directory mkdir -p "${OUTPUT_DIR}" # Clean if requested if [[ "${CLEAN_BUILD}" == "yes" ]]; then display_alert "AMLOGIC TODO: Cleaning build directory" "${SOURCE_DIR}" "info" cd "${SOURCE_DIR}" make distclean 2>/dev/null || true fi # AMLOGIC TODO: Implement actual U-Boot build # This should include: # 1. Configure U-Boot for the target board # 2. Build U-Boot # 3. Package the output display_alert "AMLOGIC TODO: U-Boot build not yet implemented" "Using Armbian native build" "warn" # For now, use Armbian's native U-Boot build cd "${SOURCE_DIR}" # Determine UBOOT_MACHINE based on board case "${BOARD}" in s6-bq201) # UBOOT_MACHINE="s6_bq201_debian" UBOOT_MACHINE="s6_bq201" ;; a9-by401) UBOOT_MACHINE="a9_by401" ;; *) display_alert "AMLOGIC TODO: U-Boot build NO BOARD define" "err" ;; esac display_alert "AMLOGIC TODO: UBOOT_MACHINE ${UBOOT_MACHINE}" "info" # AMLOGIC TODO: Uncomment below when ready to build # make "${UBOOT_MACHINE}_defconfig" # make -j$(nproc) local force_compile="${1:-}" compile_uboot_custom ${SOURCE_DIR} ${UBOOT_VERSION} ${force_compile} package_uboot_deb_amlbian_main ${SOURCE_DIR} ${UBOOT_MACHINE} "${UBOOT_VERSION}" return 0 } # ============================================================================== # Section 5: Main # ============================================================================== display_alert "AMLOGIC U-Boot Build Script" "Version: ${UBOOT_VERSION}, Board: ${BOARD}" "info" amlbian_build_uboot display_alert "AMLOGIC TODO: U-Boot build completed" "${OUTPUT_DIR}" "info" # ============================================================================== # End of build-uboot.sh # ==============================================================================