diff --git a/config/sources/families/include/sunxi64_common.inc b/config/sources/families/include/sunxi64_common.inc index bda9a192c..7b31e2122 100644 --- a/config/sources/families/include/sunxi64_common.inc +++ b/config/sources/families/include/sunxi64_common.inc @@ -16,6 +16,13 @@ declare -g BOOTENV_FILE='sunxi.txt' UBOOT_TARGET_MAP="${UBOOT_TARGET_MAP:-;;u-boot-sunxi-with-spl.bin}" declare -g BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd' declare -g LINUXFAMILY=sunxi64 +declare -g CRUST_TARGET_MAP="scp;;build/scp/scp.bin" + +[[ -n "${CRUSTCONFIG}" && -z $CRUSTSOURCE ]] && CRUSTSOURCE='https://github.com/crust-firmware/crust' +[[ -n "${CRUSTCONFIG}" && -z $CRUSTDIR ]] && CRUSTDIR='crust-sunxi-mainline' +[[ -n "${CRUSTCONFIG}" && -z $CRUSTBRANCH ]] && CRUSTBRANCH='commit:c308a504853e7fdb47169796c9a832796410ece8' +[[ -n "${CRUSTCONFIG}" && -z $CRUST_USE_GCC ]] && CRUST_USE_GCC='> 9.1.0' +[[ -n "${CRUSTCONFIG}" && -z $CRUST_COMPILER ]] && CRUST_COMPILER='or1k-elf-' case $BRANCH in diff --git a/config/sources/families/include/sunxi_common.inc b/config/sources/families/include/sunxi_common.inc index 5ee9056a4..e90a1d46d 100644 --- a/config/sources/families/include/sunxi_common.inc +++ b/config/sources/families/include/sunxi_common.inc @@ -18,6 +18,13 @@ declare -g LINUXFAMILY=sunxi declare -g UBOOT_FW_ENV='0x88000,0x20000' # /etc/fw_env.config offset and env size declare -g ASOUND_STATE='asound.state.sunxi-next' declare -g GOVERNOR=ondemand +declare -g CRUST_TARGET_MAP="scp;;build/scp/scp.bin" + +[[ -n "${CRUSTCONFIG}" && -z $CRUSTSOURCE ]] && CRUSTSOURCE='https://github.com/crust-firmware/crust' +[[ -n "${CRUSTCONFIG}" && -z $CRUSTDIR ]] && CRUSTDIR='crust-sunxi-mainline' +[[ -n "${CRUSTCONFIG}" && -z $CRUSTBRANCH ]] && CRUSTBRANCH='commit:c308a504853e7fdb47169796c9a832796410ece8' +[[ -n "${CRUSTCONFIG}" && -z $CRUST_USE_GCC ]] && CRUST_USE_GCC='> 9.1.0' +[[ -n "${CRUSTCONFIG}" && -z $CRUST_COMPILER ]] && CRUST_COMPILER='or1k-elf-' case $BRANCH in diff --git a/extensions/sunxi-tools.sh b/extensions/sunxi-tools.sh index b16ff240c..2d8d65cea 100644 --- a/extensions/sunxi-tools.sh +++ b/extensions/sunxi-tools.sh @@ -7,6 +7,12 @@ function add_host_dependencies__sunxi_add_32_bit_c_compiler() { declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} gcc-arm-linux-gnueabi" # @TODO: convert to array later } +# Install gcc-or1k-elf for crust compilation +function add_host_dependencies__sunxi_add_or1k_c_compiler() { + display_alert "Adding or1k C compiler to host dependencies" "for sunxi bootloader compile" "debug" + declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} gcc-or1k-elf" +} + function fetch_sources_tools__sunxi_tools() { fetch_from_repo "https://github.com/linux-sunxi/sunxi-tools" "sunxi-tools" "branch:master" } diff --git a/lib/functions/artifacts/artifact-uboot.sh b/lib/functions/artifacts/artifact-uboot.sh index 0382e9a85..153e330dd 100644 --- a/lib/functions/artifacts/artifact-uboot.sh +++ b/lib/functions/artifacts/artifact-uboot.sh @@ -84,6 +84,7 @@ function artifact_uboot_prepare_version() { "${BOOTDELAY}" "${UBOOT_DEBUGGING}" "${UBOOT_TARGET_MAP}" # general for all families "${BOOT_SCENARIO}" "${BOOT_SUPPORT_SPI}" "${BOOT_SOC}" # rockchip stuff, sorry. "${ATF_COMPILE}" "${ATFBRANCH}" "${ATFPATCHDIR}" # arm-trusted-firmware stuff + "${CRUSTCONFIG}" "${CRUSTBRANCH}" "${CRUSTPATCHDIR}" # crust stuff ) declare hash_variables="undetermined" # will be set by calculate_hash_for_variables(), which normalizes the input calculate_hash_for_variables "${vars_to_hash[@]}" @@ -142,6 +143,19 @@ function artifact_uboot_build_from_sources() { fi fi + if [[ -n "${CRUSTCONFIG}" ]]; then + if [[ "${ARTIFACT_BUILD_INTERACTIVE:-"no"}" == "yes" ]]; then + display_alert "Running crust build in interactive mode" "log file will be incomplete" "info" + compile_crust + + if [[ "${CREATE_PATCHES_CRUST:-"no"}" == "yes" ]]; then + return 0 # stop here, otherwise it would build u-boot below... + fi + else + LOG_SECTION="compile_crust" do_with_logging compile_crust + fi + fi + declare uboot_git_revision="not_determined_yet" LOG_SECTION="uboot_prepare_git" do_with_logging_unless_user_terminal uboot_prepare_git diff --git a/lib/functions/cli/commands.sh b/lib/functions/cli/commands.sh index b1a1b26f3..a969808cb 100644 --- a/lib/functions/cli/commands.sh +++ b/lib/functions/cli/commands.sh @@ -60,6 +60,7 @@ function armbian_register_commands() { ["uboot"]="artifact" ["uboot-patch"]="artifact" ["atf-patch"]="artifact" + ["crust-patch"]="artifact" ["uboot-config"]="artifact" ["firmware"]="artifact" @@ -105,6 +106,7 @@ function armbian_register_commands() { ["uboot-config"]="WHAT='uboot' UBOOT_CONFIGURE='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}" ["uboot-patch"]="WHAT='uboot' CREATE_PATCHES='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}" ["atf-patch"]="WHAT='uboot' CREATE_PATCHES_ATF='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}" + ["crust-patch"]="WHAT='uboot' CREATE_PATCHES_CRUST='yes' ${common_cli_artifact_interactive_vars} ${common_cli_artifact_vars}" ["firmware"]="WHAT='firmware' ${common_cli_artifact_vars}" ["firmware-full"]="WHAT='full_firmware' ${common_cli_artifact_vars}" diff --git a/lib/functions/compilation/crust.sh b/lib/functions/compilation/crust.sh new file mode 100644 index 000000000..d6d797a2a --- /dev/null +++ b/lib/functions/compilation/crust.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2013-2023 Igor Pecovnik, igor@armbian.com +# +# This file is a part of the Armbian Build Framework +# https://github.com/armbian/build/ + +compile_crust() { + if [[ -n "${CRUSTSOURCE}" && "${CRUSTSOURCE}" != "none" ]]; then + display_alert "Downloading sources" "crust" "git" + fetch_from_repo "$CRUSTSOURCE" "$CRUSTDIR" "$CRUSTBRANCH" "yes" + fi + + if [[ $CLEAN_LEVEL == *make-crust* ]]; then + display_alert "Cleaning Crust tree - CLEAN_LEVEL contains 'make-crust'" "$CRUSTSOURCEDIR" "info" + ( + cd "${SRC}/cache/sources/${CRUSTSOURCEDIR}" || exit_with_error "crazy about ${CRUSTSOURCEDIR}" + run_host_command_logged make distclean + ) + else + display_alert "Not cleaning Crust tree, use CLEAN_LEVEL=make-crust if needed" "CLEAN_LEVEL=${CLEAN_LEVEL}" "debug" + fi + + local crustdir="$SRC/cache/sources/$CRUSTSOURCEDIR" + if [[ $USE_OVERLAYFS == yes ]]; then + crustdir=$(overlayfs_wrapper "wrap" "$SRC/cache/sources/$CRUSTSOURCEDIR" "crust_${LINUXFAMILY}_${BRANCH}") + fi + cd "$crustdir" || exit + + display_alert "Compiling Crust" "" "info" + + # build aarch64 + if [[ $(dpkg --print-architecture) == amd64 ]]; then + + local toolchain + toolchain=$(find_toolchain "$CRUST_COMPILER" "$CRUST_USE_GCC") + [[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${CRUST_COMPILER}gcc $CRUST_USE_GCC" + fi + + display_alert "Compiler version" "${CRUST_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${CRUST_COMPILER}gcc" -dumpfullversion -dumpversion)" "info" + + local target_make target_patchdir target_files + target_make=$(cut -d';' -f1 <<< "${CRUST_TARGET_MAP}") + target_patchdir=$(cut -d';' -f2 <<< "${CRUST_TARGET_MAP}") + target_files=$(cut -d';' -f3 <<< "${CRUST_TARGET_MAP}") + + advanced_patch "crust" "${CRUSTPATCHDIR}" "$BOARD" "$target_patchdir" "$BRANCH" "${LINUXFAMILY}-${BOARD}-${BRANCH}" + + # create patch for manual source changes + if [[ $CREATE_PATCHES_CRUST == yes ]]; then + userpatch_create "crust" + return 0 + fi + + declare binutils_version binutils_flags_crust="" + binutils_version=$(env PATH="${toolchain}:${PATH}" or1k-elf-ld.bfd --version | head -1 | cut -d ")" -f 2 | xargs echo -n) + display_alert "Binutils version for Crust" "${binutils_version}" "info" + + run_host_command_logged CCACHE_BASEDIR="$(pwd)" PATH="${toolchain}:${toolchain2}:${PATH}" \ + "CFLAGS='-fdiagnostics-color=always -Wno-error=attributes -Wno-error=incompatible-pointer-types'" \ + make ${CRUSTCONFIG} "${CTHREADS}" "CROSS_COMPILE='$CCACHE $CRUST_COMPILER'" + + run_host_command_logged CCACHE_BASEDIR="$(pwd)" PATH="${toolchain}:${toolchain2}:${PATH}" \ + "CFLAGS='-fdiagnostics-color=always -Wno-error=attributes -Wno-error=incompatible-pointer-types'" \ + make $target_make "${CTHREADS}" "CROSS_COMPILE='$CCACHE $CRUST_COMPILER'" + + # @TODO: severely missing logging + [[ $(type -t crust_custom_postprocess) == function ]] && crust_custom_postprocess 2>&1 + + crusttempdir=$(mktemp -d) # subject to TMPDIR/WORKDIR, so is protected by single/common error trapmanager to clean-up. + chmod 700 ${crusttempdir} + + # copy files to temp directory + for f in $target_files; do + local f_src + f_src=$(cut -d':' -f1 <<< "${f}") + if [[ $f == *:* ]]; then + local f_dst + f_dst=$(cut -d':' -f2 <<< "${f}") + else + local f_dst + f_dst=$(basename "${f_src}") + fi + [[ ! -f $f_src ]] && exit_with_error "Crust file not found" "$(basename "${f_src}")" + cp "${f_src}" "${crusttempdir}/${f_dst}" + done + + # copy license file to pack it to u-boot package later + [[ -f license.md ]] && cp license.md "${crusttempdir}"/ + + return 0 # avoid error due to short-circuit above +} diff --git a/lib/functions/compilation/uboot.sh b/lib/functions/compilation/uboot.sh index 0e0cccd5a..a6b653be7 100644 --- a/lib/functions/compilation/uboot.sh +++ b/lib/functions/compilation/uboot.sh @@ -55,6 +55,12 @@ function compile_uboot_target() { # atftempdir is under WORKDIR, so no cleanup necessary. fi + # crusttempdir comes from crust.sh's compile_crust() + if [[ -n $CRUSTSOURCE && -d "${crusttempdir}" ]]; then + display_alert "Copying over bin/elf's from crusttempdir" "${crusttempdir}" "debug" + run_host_command_logged cp -pv "${crusttempdir}"/*.bin "${crusttempdir}"/*.elf ./ # only works due to nullglob + fi + # Hook time, for extra post-processing call_extension_method "pre_config_uboot_target" <<- 'PRE_CONFIG_UBOOT_TARGET' *allow extensions prepare before configuring and compiling an u-boot target* diff --git a/lib/functions/main/config-prepare.sh b/lib/functions/main/config-prepare.sh index be056942d..3cba1dc08 100644 --- a/lib/functions/main/config-prepare.sh +++ b/lib/functions/main/config-prepare.sh @@ -204,6 +204,11 @@ function config_post_main() { ATFSOURCEDIR="${ATFDIR}/$(branch2dir "${ATFBRANCH}")" fi + if [[ -n $CRUSTSOURCE ]]; then + declare -g CRUSTSOURCEDIR + CRUSTSOURCEDIR="${CRUSTDIR}/$(branch2dir "${CRUSTBRANCH}")" + fi + declare -g CHOSEN_UBOOT=linux-u-boot-${BRANCH}-${BOARD} # So for kernel full cached rebuilds. diff --git a/lib/functions/main/default-build.sh b/lib/functions/main/default-build.sh index 40ed46c3e..da5861184 100644 --- a/lib/functions/main/default-build.sh +++ b/lib/functions/main/default-build.sh @@ -23,9 +23,9 @@ function full_build_packages_rootfs_and_image() { fi # Detour, stop if CREATE_PATCHES=yes. - if [[ "${CREATE_PATCHES}" == "yes" || "${CREATE_PATCHES_ATF}" == "yes" ]]; then + if [[ "${CREATE_PATCHES}" == "yes" || "${CREATE_PATCHES_ATF}" == "yes" || "${CREATE_PATCHES_CRUST}" == "yes" ]]; then display_alert "CREATE_PATCHES=yes during image build is not supported anymore." "First, run './compile.sh BOARD=${BOARD} BRANCH=${BRANCH} kernel-patch'; then move the patch to the correct place and commit your changes; then build the image as normal. This workflow ensures consistent hashing results." "wrn" - exit_with_error "CREATE_PATCHES=yes during image build is not supported anymore. Please use the new 'kernel-patch' / 'uboot-patch' / 'atf-patch' CLI commands." + exit_with_error "CREATE_PATCHES=yes during image build is not supported anymore. Please use the new 'kernel-patch' / 'uboot-patch' / 'atf-patch' / 'crust-patch' CLI commands." fi main_default_build_packages # has its own logging sections # requires aggregation diff --git a/lib/library-functions.sh b/lib/library-functions.sh index ace75b01b..d2b392ca1 100644 --- a/lib/library-functions.sh +++ b/lib/library-functions.sh @@ -316,6 +316,15 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true # shellcheck source=lib/functions/compilation/ccache.sh source "${SRC}"/lib/functions/compilation/ccache.sh +# no errors tolerated. invoked before each sourced file to make sure. +#set -o pipefail # trace ERR through pipes - will be enabled "soon" +#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled +set -o errtrace # trace ERR through - enabled +set -o errexit ## set -e : exit the script if any statement returns a non-true return value - enabled +### lib/functions/compilation/crust.sh +# shellcheck source=lib/functions/compilation/crust.sh +source "${SRC}"/lib/functions/compilation/crust.sh + # no errors tolerated. invoked before each sourced file to make sure. #set -o pipefail # trace ERR through pipes - will be enabled "soon" #set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled