#!/bin/bash set +o posix shopt -s extglob ##################################################################################### # Script : sdcards.build # Purpose: Build Slackware Installer images for supported Hardware Models. # Author : Stuart Winter # Date...: 09-Feb-2021 ##################################################################################### # Note: this script requires that the following scripts have been run. # * ARM Trusted Firmware (atb.build) # * U-Boot binaries (uboot.build) # # 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. ##################################################################################### source /usr/share/slackdev/buildkit.sh # This is packaged in the 'd' series on Slackware ARM/AArch64. which kpartx 2>&1 > /dev/null || { echo "kpartx is required. You can find it in the 'd' Slackware package series"; exit 1; } # If '$PKGSTORE_OVERRIDE' exists as a directory, it means we have # test packages outside of the main tree. # Set $PKGSTORE to this directory to find the Kernel package: [ -d "$PKGSTORE_OVERRIDE" ] && { echo "Using PKGSTORE_OVERRIDE: $PKGSTORE_OVERRIDE" export PKGSTORE=$PKGSTORE_OVERRIDE ;} # This is either the 'root' of the Slackware tree, or is overridden to a pseudo 'root' dir # where the test assets are stored: [ -d "${ROOTDIR_OVERRIDE}" ] && rootdir="${ROOTDIR_OVERRIDE}" || rootdir=$PORTROOTDIR TMP=/tmp/build-sdcard-images CWD=$PWD OUT=$CWD/../installer/$SLACKWAREVERSION BINS=$CWD/../bin/ RECOVERYIMGDIR=$CWD/../recovery/ MNTPOINT=/tmp/sdcard-mount1 MNTPOINT1=/tmp/sdcard-mount2 rm -rf $TMP mkdir -p $OUT $RECOVERYIMGDIR $MNTPOINT $MNTPOINT1 # Flags: These can be overridden for each Hardware Model within their # functions script. # # By default we won't build the version of U-Boot that can be booted from # an SD card image. These are used for the Recovery Images which are built and tested # once, unlike the SD card images containing the Slackware Installer which are tested # regularly. # Note: this may be overriden by the Hardware Model/SoC's build function, so also # check the SoC's script directly - e.g. 'platform/aarch64/rk3399/sdcards.build-functions' BUILD_SD_RECOVERYIMG=No #BUILD_SD_RECOVERYIMG=Yes # If '$PKGSERIES_OVERRIDE' is set, use that to locate the Slackware Kernel # package's source directory. This is to enable this script to find the # WIP (Work In Progress) versions of the Kernel Module Loader and other # assets copied from the Kernel package source directory. K_SRCDIR=${PKGSERIES_K_OVERRIDE:-k} # Determine which Kernel version we're shipping with this build of the SD cards # because these will be rebuilt with each Kernel, and will be used to identify # which a user downloaded should they require support. # eval $( grep -E '^export BUILD' $PORTSRC/source/$K_SRCDIR/arm/build ) eval $( grep -E '^export VERSION' $PORTSRC/source/$K_SRCDIR/arm/build ) [ -z "${VERSION}" ] && { echo "Unable to determine Kernel version number from primary Kernel package build script" ; exit 1 ;} [ -z "${BUILD}" ] && { echo "Unable to determine Kernel package build number primary Kernel package build script" ; exit 1 ;} echo "Bundling SD Card with Kernel: $VERSION, build: $BUILD" # 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_installbootloaderconfig \ hwm_configure_extlinux \ hwm_sdimagefile_initialise \ hwm_sdimagefile_initialise_post \ hwm_sdimage_partition \ hwm_sdimage_partition_post \ hwm_sdimage_kpartx_attach \ hwm_sdimage_mkfs \ hwm_sdimage_premount \ hwm_sdimage_mount \ hwm_sdimage_postmount \ hwm_sdimage_install_hwm_assets \ hwm_sdimage_preumount \ hwm_sdimage_umount \ hwm_sdimage_postumount \ hwm_sdimage_label \ hwm_sdimage_fsck \ hwm_sdimage_uboothdr \ hwm_sdimage_predetach \ hwm_sdimage_detach \ hwm_sdimage_postdetach \ hwm_sdimage_compress \ hwm_sdimage_installtotree \ hwm_sdimage_finalise \ hwm_sdimage_recovery_build \ hwm_sdimage_recovery ; do unset -f $fname ; done } # Build the SD card image: function build_sdcard() { local assetname=$1 local soc=$2 local bootconfig=$3 local slkportarch=$4 # Prepare the generic SD root filesystem: prepare_sdroot # Load the build functions if there are any for this SoC/chipset. unset_hwm_buildfunctions [ -s $CWD/platform/${slkportarch}/${soc}/sdcards.build-functions ] && \ { echo "Loading build functions for ${soc}" . $CWD/platform/${slkportarch}/${soc}/sdcards.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 $soc" ; exit 1 ;} ;} ################################################################################################ # U-Boot/Extlinux configuration file installation and adjustment ################################################################################################ # Call a Hardware Model build function if present, otherwise # build using the standard method: errmsg="*** Failed to install boot loader config for device: $soc" fnexists hwm_installbootloaderconfig && { hwm_installbootloaderconfig || { echo "$errmsg" ; exit 1 ;} ;} || \ { echo "*** Installing standard boot loader config ***" # Copy the non-packaged parts for U-Boot's 'sysboot' feature: mkdir -vpm755 $TMP/sdroot/extlinux install -vpm644 $CWD/sdcards-skeleton/extlinux/extlinux.conf $TMP/sdroot/extlinux/ # The only option is to boot the installer: cat $CWD/sdcards-skeleton/extlinux/slkinstaller.${bootconfig} >> $TMP/sdroot/extlinux/extlinux.conf # This will be appended to extlinux.conf from within the installer. # I did experiment with the 'INCLUDE' feature of sysboot but it # seems buggy - having a single INCLUDE with a single definition caused # it to be repeated twice within the menu. # This 'slkos' file will be deleted from within the installer once # the user elects to remove the installer from the SD card. # This file is used within the installer and is appended to /boot/extlinux/extlinux.conf # by /usr/lib/setup/armedslack-SetPartitions install -vpm644 $CWD/sdcards-skeleton/extlinux/slkos.${bootconfig} \ $TMP/sdroot/extlinux/slkos.sample \ || { echo "$errmsg" ; exit 1 ;} ;} # Substitute any changes to the standard extlinux config: errmsg="*** Failed to configure extlinux config for device: $soc" fnexists hwm_configure_extlinux && { hwm_configure_extlinux || { echo "$errmsg" ; exit 1 ;} ;} || \ { echo "*** Configuring extlinux with standard changes ***" # We don't need any extra settings as standard: sed -i 's?%CMDLINE%??g' $TMP/sdroot/extlinux/* \ || { echo "$errmsg" ; exit 1 ;} ;} ################################################################################################ # SD Image file initialisation ################################################################################################ # Call a Hardware Model function to perform any tasks at this stage. errmsg="*** Failed SD image file initialisation function for device: soc" fnexists hwm_sdimagefile_initialise && { hwm_sdimagefile_initialise || { echo "$errmsg" ; exit 1 ;} ;} || \ { echo "*** Initialising SD card image using standard settings ***" # Create an empty image file: IMAGESIZE=4GB # The padding method seems to cause problems where images are >700MB. # After excercising the filesystem (making changes to the content), # U-Boot often fails: the boot ROM loads but then SPL cannot find the SD card. # dd if=/dev/zero bs=1k of=$TMP/${assetname}.img seek=$((${IMAGESIZE}-1)) count=1 #dd if=/dev/zero bs=1k of=$TMP/${assetname}.img count=$IMAGESIZE conv=notrunc status=progress fallocate -l ${IMAGESIZE} $TMP/${assetname}.img || exit 1 # Add it as a device and find out where it's gone (probably /dev/loop0): DEVLOC=$( basename $( losetup -f --show $TMP/${assetname}.img ) ) echo "Image file device location: $DEVLOC" \ || { echo "$errmsg" ; exit 1 ;} ;} # Call a Hardware Model post image file creation function: fnexists hwm_sdimagefile_initialise_post && { hwm_sdimagefile_initialise_post || \ { echo "*** Failed Hardware Model sd image post creation function for $soc" ; exit 1 ;} ;} ################################################################################################ # SD Image file initialisation: create partition table ################################################################################################ # Call a Hardware Model function to perform any tasks at this stage. errmsg="*** Failed partition table function for device: $soc" if ! fnexists hwm_sdimage_partition ; then echo "*** Configuring standard partition table ***" # A single ext4 partition, starting at 3Mbytes in, to provide # space for U-Boot et al (not presntly used since it became unstable - # it seemed to corrupt U-Boot, I think the ATF was failing after writes # to the filesystem): #1M,,,* #,,L cat < ${assetname}-sdimg_${VERSION}_${BUILD}.img.xz.md5 ) \ || { echo "$errmsg" ; exit 1 ;} ;} # Any Hardware Model final tasks before completion: errmsg="*** Failed finalisation function for device: $soc" fnexists hwm_sdimage_finalise && { hwm_sdimage_finalise || { echo "$errmsg" ; exit 1 ;} ;} # Build the SD card Recovery Image if configured within the Hardware Model's # build functions: if [ "$BUILD_SD_RECOVERYIMG" = "Yes" ]; then fnexists hwm_sdimage_recovery && { hwm_sdimage_recovery || { echo "*** Failed SD Recovery Image for SoC $soc" ; exit 1 ;} ;} fi echo "*** SD Card build complete for $soc" } # Unpack generic Kernel package: # Note: this may require breaking out into callout helpers to support other Hardware Models # in the future. function prepare_sdroot(){ rm -rf $TMP/{sdroot,extract-pkgs} mkdir -p $TMP/{sdroot,extract-pkgs} pushd $TMP/extract-pkgs explodepkg $PKGSTORE/a/kernel_*-+([^-])-+([^-])-+([^-]).t[gblx]z # Create the symlinks for the initrd, Kernel, System.map and dtb: # We're extracting only the symlink creation code incase we add anything sexy # into the doinst.st script in the future: grep -E '^\( cd boot.*(rm|ln)' install/doinst.sh | bash # The OS InitRD doesn't need to be within this image, as # it will be installed during the OS installation. rm -fv boot/initrd-* # In Slackware AArch64, /boot (at least on the RockPro64) will be # an ext4 FS on the SD card. # Let's move the files relative to that configuration: mv -fv boot/* $TMP/sdroot/ # Copy the installer initrd: install -vpm644 $rootdir/installer/initrd-*.img $TMP/sdroot/ popd } ##################### Build the SD card images ######################################## # Build SD cards for the supported Hardware Models: # Note: The Pinebook Pro uses the 'rk3399' assets. # Format: # # RockPro64 and Pinebook Pro: build_sdcard rk3399_generic rk3399 generic aarch64 || \ { echo "Failed build for rk3399 generic" ; exit 1 ;} # Raspberry Pi 4: build_sdcard bcm2711_rpi4 bcm2711 generic aarch64 || \ { echo "Failed build for bcm2711 rpi4" ; exit 1 ;} # Raspberry Pi 3: # Despite using a different SoC, the Raspberry Pi assets are all included within the RPi4 SD image, # and the same U-Boot binary on both Hardware Models. Therefore we'll symlink the image: ln -rvfs $OUT/bcm2711_rpi4-sdimg_${VERSION}_${BUILD}.img.xz $OUT/bcm2837_rpi3.sdimg_latest.img.xz # # **** Note: if this changes, the 'sa64-instwrite' script needs to be updated. ***** # # However, if it requires a separate version of any config or binary # (U-Boot for example), we'll need to build its own version. #build_sdcard bcm2837_rpi3 bcm2837 generic aarch64 || \ # { echo "Failed build for bcm2837 rpi3" ; exit 1 ;} # Example for other Hardware Models # The Pinebook Pro (whilst using the same RK3399 SoC as # the RockPro64) requires divergence: create a separate SD card image: #build_sdcard rk3399_pinebookpro rk3399 generic aarch64 || exit 1 # Solid-Run Honeycomb LX2160A # Note: "GRUB" is specified as the Boot Loader config. # # Hack: The Honeycomb sdcard helper script re-defines the extlinux config # function to prevent installing unnecessary U-Boot assets. # At some point we can enhance sdcards.build to handle config files for # other Boot Loaders, but for the time being this hack is good enough. build_sdcard honeycomb_lx2160acex7 lx2160acex7 GRUB aarch64 || \ { echo "Failed build for Honeycomb lx2160acex7" ; exit 1 ;} echo "*** sdcards.build : complete for all Hardware Models"