#!/bin/bash ########################################################################## # Script : uboot.build # Purpose: Build u-boot for Slackware AArch64's supported Hardware Models # Author : Stuart Winter # Date...: 09-Feb-2021 ########################################################################## # Copyright 2021, 2022 Stuart Winter, Donostia, Spain. # All rights reserved. # # Redistribution and use of this script, with or without modification, is # permitted provided that the following conditions are met: # # 1. Redistributions of this script must retain the above copyright # notice, this list of conditions and the following disclaimer. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO # EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ########################################################################## # References: # These may be helpful for the community when supporting other Hardware Models. # http://opensource.rock-chips.com/wiki_Partitions # https://stikonas.eu/wordpress/2019/09/15/blobless-boot-with-rockpro64/ # https://casualhacking.io/blog/2018/7/8/diy-root-of-trust-using-arm-trusted-firmware-on-the-96boards-hikey # https://wiki.radxa.com/Rock/make_sd_image # https://wiki.amarulasolutions.com/bsp/rockchip/rk3399/rockpro64.html # https://forum.armbian.com/topic/12639-mainline-spi-nvme-boot-working-rockpro64-with-armbian/ # https://forum.pine64.org/showthread.php?tid=8174 # https://github.com/ayufan-rock64/linux-build/blob/master/recipes/flash-spi.md # https://u-boot.readthedocs.io/en/latest/board/rockchip/rockchip.html # # The code to build a version of U-Boot for flashing to SPI is taken from: # https://raw.githubusercontent.com/sigmaris/u-boot/v2020.01-ci/azure-pipelines.yml # Thanks to sigmaris on the Pine64 forum for the build recipe. # https://forum.pine64.org/showthread.php?tid=8685 ##################################################################################### source /usr/share/slackdev/buildkit.sh CWD=$PWD TMP=/tmp/build-uboot BINS=$PWD/../bin/ # Set/reset defaults. # These variables may have been overridden by the Hardware Model build functions # so we need to reset them before building for each Hardware Model. function set_default_vars() { # U-Boot version: # Hardware Model build functions may overwrite this version within their 'hwm_initialise' # function. They'll also want to override function 'hwm_uboot_src_patch' if doing so # in case the set of patches don't apply to the other version. #UBOOTVER="2022.04" # prev working ver UBOOTVER="2023.01" } # Unset callout functions from a previous platform's build # receipe. # The function names are prefixed by 'hwm_' which stands for # Hardware Model. function unset_hwm_buildfunctions() { local fname for fname in \ hwm_initialise \ hwm_uboot_src_unpack_pre \ hwm_uboot_src_unpack \ hwm_uboot_src_unpack_post \ hwm_uboot_src_patch \ hwm_configure_uboot \ hwm_build_uboot_pre \ hwm_build_uboot \ hwm_build_uboot_post \ hwm_install_pre \ hwm_install \ hwm_install_post \ hwm_build_spi \ hwm_build_sdrecovery \ hwm_build_final ; do unset -f $fname ; done } # Build u-boot for the specified device: function build_bootloader() { # Set/reset default variables that may have been changed by a previous # build from one of the Hardware Model's build functions: set_default_vars local devicetype=$1 local chipset=$2 local assetname=$3 local slkportarch=$4 echo "Device type..: ${devicetype}" echo "Chipset name : ${chipset}" echo "Asset name...: ${assetname}" echo "Architecture : ${slkportarch}" echo "**********************************" # I want the output file names to be lower case since some are 'Orange' and others 'orange' # which would just makes my documentation more complex. local lc_devicetype=$( echo $devicetype | tr '[A-Z]' '[a-z]' ) # Load the build functions if there are any for this chipset. unset_hwm_buildfunctions [ -s $CWD/platform/${slkportarch}/${chipset}/uboot.build-functions ] && \ { echo "Loading build functions for ${chipset}" . $CWD/platform/${slkportarch}/${chipset}/uboot.build-functions ;} # Call a Hardware Model initialisation function. # The purpose of this is to override any settings such as the version # of U-Boot, should your Hardware Model be using a different version. fnexists hwm_initialise && { hwm_initialise || \ { echo "*** Failed Hardware Model Initialisation function for device $devicetype" ; exit 1 ;} ;} ############################################################################ # U-Boot src unpack ############################################################################ rm -rf $TMP mkdir -p $TMP # Call a Hardware Model pre- build function, if present: # The purpose of this is to perform any hacks prior to unpacking the source # such as changing the version of U-Boot from that within this caller script. fnexists hwm_uboot_src_unpack_pre && { hwm_uboot_src_unpack_pre || \ { echo "*** Failed pre U-Boot src extraction function for device $devicetype" ; exit 1 ;} ;} echo "U-Boot version: ${UBOOTVER}" sleep 10 # Call a Hardware Model installation function if present, otherwise # build using the standard method: errmsg="*** Failed U-Boot src extraction for device: $devicetype" fnexists hwm_uboot_src_unpack && { hwm_uboot_src_unpack || { echo "$errmsg" ; exit 1 ;} ;} || \ { # Unpack U-boot source echo "*** Unpacking U-Boot src using standard routine ***" cd $TMP tar xf $CWD/sources/u-boot-$UBOOTVER.tar.?z* cd u-boot*/ || exit 1 make mrproper || { echo "$errmsg" ; exit 1 ;} ;} # Call a Hardware Model installation function if present, otherwise # build using the standard method: errmsg="*** Failed to apply patches to U-Boot for : $devicetype" fnexists hwm_uboot_src_patch && { hwm_uboot_src_patch || { echo "$errmsg" ; exit 1 ;} ;} || \ # Note that we're already in the U-Boot directory. { # Patch U-Boot source: echo "*** Patching U-Boot src using standard routine ***" # Apply patches: for pf in \ 0001-PBP-Fix-panel-reset.patch \ 0003-Turn-power-and-standby-LEDs-on-early.patch \ 0004-mmc-sdhci-allow-disabling-sdma-in-spl.patch \ 0005-arm-dts-Work-around-daughterboard-issues.patch ; do auto_apply_patch $CWD/sources/patches/uboot/$pf || failpatch done || { echo "$errmsg" ; exit 1 ;} ;} # for pf in $CWD/sources/patches/uboot/* ; do # auto_apply_patch $pf || failpatch # done || { echo "$errmsg" ; exit 1 ;} ;} # Call a Hardware Model post src-extraction function, if present: # The purpose of this is to apply any patches for a particular Hardware Model. fnexists hwm_uboot_src_unpack_post && { hwm_uboot_src_unpack_post || \ { echo "*** Failed post U-Boot src extraction function for device $devicetype" ; exit 1 ;} ;} ############################################################################ # U-Boot configuration ############################################################################ echo "*** Configuration - installing config file***" rm -f .config # If we had a separate U-Boot config file for two or more Hardware Models that # shared a chipset, we would name our configs thusly: # platform/aarch64/rk3399/uboot.config_rockpro64-rk3399 # platform/aarch64/rk3399/uboot.config_pinebook-pro-rk3399 if [ -s $CWD/platform/${slkportarch}/${chipset}/uboot.config_${devicetype} ]; then echo "Using custom U-Boot config: $CWD/platform/${slkportarch}/${chipset}/uboot.config_${devicetype}" cp -fa $CWD/platform/${slkportarch}/${chipset}/uboot.config_${devicetype} .config # Should it need aligning: make V=1 oldconfig else # Take the default board config: echo "*** Building for ${devicetype} using default U-Boot config ***" # make BL31=$BINS/$chipset/bl31.elf V=1 ${devicetype}_defconfig oldconfig make V=1 ${devicetype}_defconfig oldconfig # Enable boot logo: # The U-Boot logo is enabled by default, so it's easier to overwrite # the default with Slackware's: cp -fav $CWD/sources/slacklogo/slack.bmp ./drivers/video/u_boot_logo.bmp # The proper way, required for pre 2022 release: # Can't get it to work on the 2021 release. oh well. roll on 22. #sed -i 's?# CONFIG_CMD_BMP is not set?CONFIG_CMD_BMP=y?g' .config #sed -i '\?^# CONFIG_SPLASH_SCREEN is not set.*? a\# CONFIG_SPLASH_SCREEN_ALIGN is not set' .config #sed -i '\?^# CONFIG_SPLASH_SCREEN_ALIGN is not set.*? a\# CONFIG_VIDEO_BMP_GZIP is not set' .config #cp -fav $CWD/sources/slacklogo/slack.bmp ./tools/logos/u-boot_logo.bmp #cp -fav $CWD/sources/slacklogo/slack.bmp ./tools/logos/denx.bmp fi # echo "*** Configuration - Slackware customisations***" # Brand it: sed -i 's?^CONFIG_IDENT_STRING=.*?CONFIG_IDENT_STRING=" Slackware"?g' .config # # We use a compressed Kernel: #sed -i 's?#define CONFIG_SYS_BOOTM_LEN.*?#define CONFIG_SYS_BOOTM_LEN 0x8000000?g' common/bootm.c # # Increase the logging: #sed -i 's?LEVEL=4?LEVEL=9?g' .config # # Call the chipset's U-Boot configuration function (if set): fnexists hwm_configure_uboot && { hwm_configure_uboot || \ { echo "*** Failed to configure for device $devicetype" ; exit 1 ;} ;} ############################################################################ # Build U-Boot ############################################################################ # Call a Hardware Model pre- build function, if present: # The purpose of this is to perform any hacks prior to the build. fnexists hwm_build_uboot_pre && { hwm_build_uboot_pre || \ { echo "*** Failed pre U-Boot build function for device $devicetype" ; exit 1 ;} ;} # Call a Hardware Model build function if present, otherwise # build using the standard method: errmsg="*** Failed to build for device: $devicetype" fnexists hwm_build_uboot && { hwm_build_uboot || { echo "$errmsg" ; exit 1 ;} ;} || \ { echo "*** Building using standard options ***" make $NUMJOBS V=1 BL31=$BINS/$chipset/bl31.elf all u-boot.itb || { echo "$errmsg" ; exit 1 ;} ;} ## ### This is useful but needs to be in the proper place ### At the moment this fixes only a cosmetic issue with u-boot which ### can be corrected by 'saveenv'. ### Needs a bit more work to blend this in completely. # Copy built-in env object and extract env data cp env/built-in.o built_in_env.o objcopy -O binary -j ".rodata.default_environment" built_in_env.o # Replace null terminator in built-in env with newlines tr '\0' '\n' < built_in_env.o | sed '/^$/d' > built_in_env.txt # Make built-in env image with correct CRC # tools/mkenvimage -s 0x8000 -o $TMP/spi/spi_default_env.img built_in_env.txt tools/mkenvimage -s 0x8000 -o built_in_env.o built_in_env.txt #### # Call a Hardware Model post build function, if present: # The purpose of this is to perform any hacks post build. fnexists hwm_build_uboot_post && { hwm_build_uboot_post || \ { echo "*** Failed post U-Boot build function for device $devicetype" ; exit 1 ;} ;} # Notes for making images: # Combined for U-Boot on SPI flash: #mkimage -n rk3399 -T ${ubootimgtype} -d tpl/u-boot-tpl.bin:spl/u-boot-spl.bin ${devicetype}_uboot.bin # U-Boot for SD card booting: ## TEMPORARY:::: # if [ "$devicetype" = "rockpro64-rk3399" ]; then # mkimage -n rk3399 -T rksd -d ./tpl/u-boot-tpl-dtb.bin /tmp/${devicetype}_uboot.bin || exit 1 # cat ./spl/u-boot-spl-dtb.bin >> /tmp/${devicetype}_uboot.bin || exit 1 # fi ############################################################################ # Install U-Boot ############################################################################ # Call a Hardware Model post build function, if present: # The purpose of this is to perform any hacks prior to completing the build for # this Hardware Model. fnexists hwm_install_pre && { hwm_install_pre || \ { echo "*** Failed pre-installation function for device $devicetype" ; exit 1 ;} ;} # Install the U-boot components ready for the 'sdcards.build' script: # Wipe the previous versions of U-Boot: rm -rfv $BINS/$chipset/u-boot-*/${assetname}* mkdir -p $BINS/$chipset/u-boot-${UBOOTVER} # Call a Hardware Model installation function if present, otherwise # build using the standard method: errmsg="*** Failed installation for device: $devicetype" fnexists hwm_install && { hwm_install || { echo "$errmsg" ; exit 1 ;} ;} || \ { # These generally aren't required as users will only need the final U-Boot binary, but # we include them should users want to experiment. echo "*** Installing U-Boot binaries into tree using standard routine ***" install -vpm644 idbloader.img $BINS/$chipset/u-boot-${UBOOTVER}/${assetname}-idbloader.img install -vpm644 u-boot.itb $BINS/$chipset/u-boot-${UBOOTVER}/${assetname}-u-boot.itb || \ { echo "$errmsg" ; exit 1 ;} ;} # Call a Hardware Model post build function, if present: # The purpose of this is to perform any hacks prior to completing the build for # this Hardware Model. fnexists hwm_install_post && { hwm_install_post || \ { echo "*** Failed post installation function for device $devicetype" ; exit 1 ;} ;} # For boards to which we'll write Slackware AArch64's U-Boot to SPI, # let's build the SPI versions: rm -rf $TMP/spi mkdir -p $TMP/spi fnexists hwm_build_spi && { hwm_build_spi || { echo "*** Failed SPI U-Boot build for device $devicetype" ; exit 1 ;} ;} # Build U-Boot binaries for the SD card Recovery/Initialisation Images. # These are required on some Hardware Models to install a version of U-Boot capable of # booting the Slackware Installer, where a newer version of U-Boot can be installed. # They're also to cater for the situation where the SPI Flash goes bad (which happened # on numerous occasions during the development of the Slackware AArch64 port!), where # one can insert the MicroSD card and have it reflash. # # The SD card images use the 'rk3399_rockpro64-sd-idbloader.img' # binaries. # The actual SD card image is created by 'sdcards.build' which uses the binaries # created by this script ('uboot.build'): rm -rf $TMP/sdrecovery mkdir -p $TMP/sdrecovery # There is no standard for this, since it depends on each Hardware Model. # The Rpi4 does not have nor need one since our U-Boot is deployed to the Micro SD card boot Storage device # on the primary partition. fnexists hwm_build_sdrecovery && { hwm_build_sdrecovery || { echo "*** Failed SD U-Boot build for device $devicetype" ; exit 1 ;} ;} # Call a Hardware Model post build function, if present: # The purpose of this is to perform any hacks prior to completing the build for # this Hardware Model. fnexists hwm_build_final && { hwm_build_final || \ { echo "*** Failed finalisation build function for device $devicetype" ; exit 1 ;} ;} echo "*** Build for $devicetype complete ***" } # Build the known devices: # :: # Note: for the Pinebook Pro it'll use the RockPro64 assets. # If Hardware Models using the same SoC require customisations, you'd change # the asset name. # These asset names are used by 'sdcards.build' build_bootloader rpi_arm64 bcm2711 bcm2711_rpi4 aarch64 || \ { echo "Failed build for RPi4 (rpi_arm64)" ; exit 1 ;} #exit # This is if the RPi3 requires a different U-Boot config than the RPi4. # To be determined. #build_bootloader rpi_arm64 bcm2837 bcm2837_rpi3 aarch64 || \ # { echo "Failed build for RPi3 (rpi_arm64)" ; exit 1 ;} build_bootloader rockpro64-rk3399 rk3399 rk3399_rockpro64 aarch64 || \ { echo "Failed build for rockpro64-rk3399" ; exit 1 ;} # Whilst Slackware ships a 'generic' rk3399 Slackware installer, the # U-Boot binaries are configured/built for each Hardware Model. # The only point of divergence presently is the U-Boot config: # 'pinebook-pro-rk3399_defconfig' vs 'rockpro64-rk3399_defconfig' build_bootloader pinebook-pro-rk3399 rk3399 rk3399_pinebookpro aarch64 || \ { echo "Failed build for pinebook-pro-rk3399" ; exit 1 ;} echo "*** uboot.build : complete for all Hardware Models"