#!/bin/bash set +o posix shopt -s extglob ########################################################################## # Script : kernel.SlackBuild # Purpose: Natively build and package the Linux Kernel for Slackware ARM # Author : Stuart Winter # Date...: 22-Nov-2024 ########################################################################## # Changelog ############ # 22-Nov-24: # * Merged the 'a/kernel-modules' package into a single 'a/kernel_armv8' # to be inline with x86. # 01-Jan-24: # Implemented a shared Kernel module list 'sources/kmod-dirlist' between # the OS InitRD and Slackware Installer. # 10-Feb-22: # Build a/kernel-modules & d/kernel-headers package to reduce build time # for Kernel packages, and ease maintenance of stable releases. # 20-Apr-21: # Updated for AArch64. # Removed legacy ARM initrd creation code. # 01-Apr-2018: # * Handle building Kernels in /patches # * Simplify and remove duplication of code. # 20-Sep-2005 # * First version for Linux 2.6.13.1 on the StrongARM RiscPC # 31-Dec-2005 # * Linux 2.6.14.5 ########################################################################## # # Copyright 2005-2024 Stuart Winter, Earth, Milky Way, "". # 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. # # Record toolchain & other info for the build log: slackbuildinfo # Paths to skeleton port's source & real Slackware source tree: export CWD=$PWD # Detect whether we're building for /patches: This function sets the variable 'SLACKPATCHING' slack_findpkgstore_is_stablerelease echo "Building in /patches/? $SLACKPATCHING" # Temporary build locations: export TMPBUILD=$TMP/build-$PKGNAM export PKG=$TMP/package-$PKGNAM # Delete & re-create temporary directories then cd into $TMPBUILD mkpkgdirs # When using xz with tar, set the options: #export XZ_OPTS="--threads $(( $(nproc) -1 )) -ze9f -C crc32" export XZ_OPTS="--threads=0 -ze9f -C crc32" # OS InitRD & Slackware Installer Kernel module include list: KMODINCLUDELIST=$CWD/sources/kmod-dirlist [ ! -f ${KMODINCLUDELIST} ] && { echo "ERROR: Kernel module include list not found" ; exit 1 ;} # Default location into which the Linux src will be unpacked: KERNELSRCDIR=$TMPBUILD/kernel-src mkdir -p $KERNELSRCDIR # Parse any command line operators: PARAMS="$( getopt -qn "$( basename $0 )" -o P:s:n -l pkgstoreoverride:,srcdir:,noconfig,nopatches -- "$@" )" eval set -- "${PARAMS}" for param in $*; do case "$param" in -n|--noconfig) NOPLACECONFIG=Yes shift ;; -p|--nopatches) NOAPPLYPATCHES=Yes shift ;; -P|--pkgstoreoverride) PKGSTORE_OVERRIDE="$2" # This is set so that the 'kernels' directory in the Slackware ARM # source isn't overwritten with test Kernels when users are building packages. ROOTDIR_OVERRIDE="$2" shift 2;; -m|--mergeconfig) MERGECONFIG="$2" shift 2;; -s|--srcdir) KERNELSRCDIR="$2" ALTERNATEKSRC=Yes shift 2;; --) shift; break;; esac done # If the user has specified -P/--pkgstoreoverride, they want to store the resulting # package files in a directory other than $PKGSTORE. # We cannot override $PKGSTORE because this build script extracts assets from # packages within $PKGSTORE. Packages include 'a/bash'. # We will ensure that the destination directory exists. [ ! -z "${PKGSTORE_OVERRIDE}" -a ! -d "${PKGSTORE_OVERRIDE}" ] && { echo "ERROR: Alternate package destination directory '${PKGSTORE_OVERRIDE}' does not exist" exit 1 ;} || { echo "Packages will be stored in: ${PKGSTORE_OVERRIDE}" ;} # If the user has specified --srcdir to an unpacked Linux source tree, # enter that. Otherwise unpack the source held within the Slackware ARM src tree. # Extract the kernel source: [ ! -d "$KERNELSRCDIR" ] && { echo "Error: unable to find directory $KERNELSRCDIR" ; exit 1 ;} cd $KERNELSRCDIR if [ "$ALTERNATEKSRC" = "Yes" ]; then echo "Entering unpacked Linux Kernel source directory $KERNELSRCDIR" else echo -n "Extracting Kernel source... " tar xf $CWD/sources/linux-*.tar.xz || exit 1 echo "done" # Make the source tree dir name match $VERSION (useful for rc releases) mv -fv linux-* linux-$VERSION fi # If the user specified their own existing Kernel src tree, does the # directory format match what we need? [ ! -d linux-$VERSION ] && { echo "Error: unable to find Linux kernel source directory linux-$VERSION" ; exit 1; } # Enter the Linux Kernel source directory: cd linux-*/ || exit 1 # Set permissions: slackhousekeeping # Install the appropriate Kernel config file, unless # the --noconfig option was supplied. [ -z "$NOPLACECONFIG" ] && install -vpm644 $CWD/configs/config-$SLKKERNELARCH .config # Merge a config in? This is used for onboarding new Hardware Models. [ -f "$MERGECONFIG" ] && { echo "Merging in Kernel configuration file $MERGECONFIG" ./scripts/kconfig/merge_config.sh .config $MERGECONFIG ;} # Remove any hyphen from the EXTRAVERSION name. sed -i '/EXTRAVERSION *=/s/-//g' Makefile # Ensure that the Kernel version reported in the Makefile matches # the version in the package name that we plan to use. # # If we're doing builds of RC kernels, we can ignore this check and assume we performed the # necessary due dilligence. Non-RC releases have no 'EXTRAVERSION' value set. # if ! echo "$VERSION" | grep -E "rc|next" ; then if [ "$( echo "$(sed -ne's/^VERSION *= *//p' Makefile).$(sed -ne's/^PATCHLEVEL *= *//p' Makefile).$(sed -ne's/^SUBLEVEL *= *//p' Makefile)" )" != $VERSION ]; then echo "**** Package name vs Kernel version mismatch ****" echo "*** Slackware Packaging Version: $VERSION" echo "*** Kernel versions (From files): $( sed -ne's/^VERSION *= *//p' Makefile).$(sed -ne's/^PATCHLEVEL *= *//p' Makefile).$(sed -ne's/^SUBLEVEL *= *//p' Makefile )" exit 1 fi fi echo "Kernel Slackware package version: $VERSION" # Apply patches unless --nopatches command line option was specified, or # there are none available in the source tree: ls $CWD/sources/patches/!(*debian*|*no-autopatch*)xz* > /dev/null 2>&1 || NOAPPLYPATCHES=Yes [ -z "$NOAPPLYPATCHES" ] && { #[ "$SLKPORTARCH" = "aarch64" ] && { auto_apply_patch $CWD/sources/patches/0103-futex-no-autopatch.patch.xz || failpatch ;} for i in $CWD/sources/patches/!(*debian*|*no-autopatch*)xz* ; do auto_apply_patch $i || failpatch done ;} # For GCC-10: sed -i "s/--param=allow-store-data-races=0/-fno-allow-store-data-races/g" Makefile #tar xvvf $CWD/sources/patches/linux*debian*z #for i in debian/patches/features/arm/* ; do # auto_apply_patch $i || exit 1 #done #for i in debian/patches/bugfix/arm/* ; do # auto_apply_patch $i || exit 1 #done # Build Kernel echo "Cleaning Kernel.." make clean echo "******************************" echo "*** Building kernel Image ***" echo "******************************" # NUMJOBS is set by the Slackware ARM build orchestration system. # If you're building this outside of the official master environment, # we'll default to the number of local processors: NUMJOBS=${NUMJOBS:--j$( nproc )} [ "$SLKPORTARCH" = "arm" ] && \ { make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y zImage || failmake ;} [ "$SLKPORTARCH" = "aarch64" ] && \ { make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y Image || failmake ;} # Build modules: echo "************************" echo "*** Building modules ***" echo "************************" make $NUMJOBS ARCH=$LINUXKERNELARCH CONFIG_DEBUG_SECTION_MISMATCH=y modules || failmake # Archive the compiled kernel source - this is used to create the kernel-source package. # The reason why we check the architecture is because with the soft float port we had # multiple kernels, but there was no need to have multiple Kernel sources. # With the hard float and aarch64 port, we have just one Kernel; but in case we end up with # more than one Kernel in the future, we'll keep this check in place. # "SLKKERNELARCH" is the _package_ name architecture not the OS architecture - e.g. it'd be "armv5", "armv7", "armv8" # e.g. the ARM port's packages are named "foo-1.0-arm-1.txz", but this particular _package_ will only run # on armv7 or greater, so its specific package architecture is "armv7". # If there is a case to require >1 kernel per arch again, there should be # a kernel-source package for it, since it would be required to build modules that we don't ship, but # that can easily be added by the user. # # The kernel-source package is now built at the end of this process rather than # from a separate build script. #if [[ "${SLKKERNELARCH}" =~ (armv7|armv8) ]]; then # echo "Archiving compiled source for kernel-source package..." # # This takes far too long on ARM. I'll let the Distro polishing script pack this one: # # ( cd .. && tar -Ixz -pcf $CWD/compiled-sources/$SLKKERNELARCH-kernel-$VERSION-compiled.tar.xz linux-$VERSION ) # ( cd .. && tar pcf $CWD/compiled-sources/$SLKKERNELARCH-kernel-$VERSION-compiled.tar linux-$VERSION ) #fi echo "Installing Kernel includes for package d/kernel-headers..." # Create package structure: mkdir -vpm755 $TMPBUILD/package-kernel-headers/{install,usr} # Install 'sanitised' headers: make ARCH=$LINUXKERNELARCH \ INSTALL_HDR_PATH=$TMPBUILD/package-kernel-headers/usr \ headers_install || failinstall ( cd $TMPBUILD/package-kernel-headers || exit 1 # Wipe these '.install' and '..install.cmd' files find . -iname '.*' -type f -print0 | xargs -0 rm -f ) # Not anymore - the glibc build uses the Kernel package headers. # echo "Archiving kernel-headers for use with glibc" # mkdir -vpm755 $CWD/sources/kernel-headers # time tar -Ixz -pcf $CWD/sources/kernel-headers/$SLKKERNELARCH-kernel-headers-$VERSION.tar.xz . ) # Install modules into the package: make ARCH=$LINUXKERNELARCH modules_install INSTALL_MOD_PATH=$PKG || failinstall # We'll install the Kernel modules to the OS once they have been # compressed within $PKG: if [ -d $PKG/lib/modules/$VERSION-$SLKKERNELARCH ]; then rm -rf /lib/modules/$VERSION-$SLKKERNELARCH else echo "ERROR: Failed build - the Kernel modules aren't present within the package tree" exit 1 fi # Needed for mkinitrd to find the modules, but we'll install # the compressed versions from $PKG since it cuts down on build time. #make ARCH=$LINUXKERNELARCH modules_install || exit 1 # Wipe the firmware from the package since it's included in the a/kernel-firmware package # and dealt with above: echo "Wiping /lib/firmware from the current package contents so that" echo "it won't be included in the a/kernel package ..." rm -rf $PKG/lib/firmware # Compress the Kernel modules that have been installed into the # package: echo "Compressing package's Kernel modules" pushd $PKG find ./lib/modules -type f -name "*.ko" | parallel xz $XZ_OPTS #find ./lib/modules -type f -name '*.ko' | xz $XZ_OPTS --files #find ./lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS {} \; # Fix symlinks now that the Kernel modules have a .xz suffix: for i in $(find ./lib/modules -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done # Install the newly-compressed Kernel modules into the OS: echo "Installing compressed Kernel modules into /lib/modules for the running OS" time cp -fa ./lib/modules/$VERSION-$SLKKERNELARCH /lib/modules/ popd # Compress OS's copy of the Linux kernel modules to reduce the size of the initrd. #echo "Compressing Host OS' Kernel modules (for $SLKKERNELARCH) with xz -e9 -- this will take 10-15 mins.." ##find /lib/modules/$VERSION-$SLKKERNELARCH -type f -name "*.ko" -exec gzip -9f {} \; #time find /lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS \; #for i in $(find /lib/modules/$VERSION-$SLKKERNELARCH -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done # Usually we'd do this inside the resulting package but we need the modules # to be up to date on the live system so that mkinitrd can grab what it needs: ( cd / echo "Updating host OS' module dependencies for $VERSION-$SLKKERNELARCH" find lib/modules -name $VERSION-$SLKKERNELARCH -type d -mindepth 1 -maxdepth 1 -printf "%f\n" | xargs -i depmod {} -b. ) # Install the kernel image and system map: mkdir -vpm755 $PKG/{install,boot} # Building zImage for ARM creates Image, and subsequently # compresses it. Since we don't ship the uncompressed version # for ARM, we'll delete it so that it doesn't get included # by the search code below. [ "$SLKPORTARCH" = "arm" ] && rm -f arch/$LINUXKERNELARCH/boot/Image #gzip -f9cv System.map > $PKG/boot/System.map-$SLKKERNELARCH-$VERSION.gz # These are named after their respective architectures so that you # can have more than 1 Kernel package installed on the system # at any one time, and configure your boot loader to boot, say # "/uImage-", and not then have to maintain Kernel version # numbers. # We'll wipe the ones we don't need for this architecture a bit # further down. install -vpm644 System.map $PKG/boot/System.map-$SLKKERNELARCH-$VERSION for imgtype in {,z,u}Image ; do [ -f arch/$LINUXKERNELARCH/boot/$imgtype ] && \ install -vpm644 arch/$LINUXKERNELARCH/boot/$imgtype $PKG/boot/$imgtype-$SLKKERNELARCH-$VERSION done # Make symlinks: ( cd $PKG/boot ln -vfs System.map-$SLKKERNELARCH-$VERSION System.map-$SLKKERNELARCH for imgtype in {,z,u}Image ; do [ -f $imgtype-$SLKKERNELARCH-$VERSION ] && \ ln -vfs $imgtype-$SLKKERNELARCH-$VERSION $imgtype-$SLKKERNELARCH done ) # The Kernel config file used (following the Slackware standard): install -pvm644 .config $PKG/boot/config-$SLKKERNELARCH-$VERSION # The package description: install -pvm644 $CWD/slack-descs/kernel-$SLKKERNELARCH $PKG/install/slack-desc # The script to handle appending DTB files to systems that have the # 'dtb=' kernel paramater specified: # Not needed for hard float port since all of the U-Boot versions are new enough # to handle loading a DTB, but we'll leave this in here and let it error out. install -pvm644 $CWD/sources/doinst.sh $PKG/install/ # Copy the Kernel into our tree's 'kernels' directory: # If the 'ROOTDIR_OVERRIDE' is set (usually by k/build_test_kernels.sh), put the assets there, # otherwise store them in the main tree: [ -d "${ROOTDIR_OVERRIDE}" ] && rootdir="${ROOTDIR_OVERRIDE}" || rootdir=$PORTROOTDIR #if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then if [ "$SLACKPATCHING" = "no" ]; then mkdir -vpm755 $rootdir/kernels/$SLKKERNELARCH for imgtype in {,z,u}Image ; do [ -f arch/$LINUXKERNELARCH/boot/$imgtype ] && \ install -vpm644 arch/$LINUXKERNELARCH/boot/$imgtype \ $rootdir/kernels/$SLKKERNELARCH/$imgtype-$SLKKERNELARCH done # This is really for the installer build script: gzip -f9cv System.map > $rootdir/kernels/$SLKKERNELARCH/System.map.gz # Install the Kernel configuration file, as this can be a useful reference: install -vpm644 .config $rootdir/kernels/$SLKKERNELARCH/config fi # Make an initrd for the architecture. # Unpack the generic Slackware Initial RAM disk ('OS initrd') tree: rm -rf $TMPBUILD/initrd-tree mkdir -vpm755 $TMPBUILD/initrd-tree tar xf /usr/share/mkinitrd/initrd-tree.tar.gz -C $TMPBUILD/initrd-tree # Unpack bash, ncurses, jfsutils and xfsprogs as we need a few # components: mkdir -p $TMPBUILD/pkg-extract/special-handling pushd $TMPBUILD/pkg-extract # Handle locating the packages from which we extract components when # building within /patches for a stable release, vs -current. #[ "$SLACKPATCHING" = "yes" ] && pkgstore=$PORTROOTDIR/slackware || pkgstore=$PKGSTORE # If we're building in patches or building test Kernels, $PKGSTORE may not contain # all or any of the packages we require to assemble the OS InitRD. # PORTROOTDIR is set in /usr/share/slackdev/slackdev.config which always points to # the correct place. # Presently, this means that we won't use any newer versions of patch packages # from within /patches, but I don't foresee this posing any issue. # PORTPATCHPKGS, PORTPATCHSRC can be used in future if necessary. # Note: 'pkgstore' is only used here to extract packages, $PKGSTORE is where the # new Kernel packages are written to. pkgstore=$PORTROOTDIR/slackware # 'a' series packages: explodepkg $pkgstore/a/bash-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/coreutils-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/hwdata-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/jfsutils-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/usbutils-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/pciutils-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/a/util-linux-+([^-])-+([^-])-+([^-]).t[gblx]z # set up symlinks for util-linux grep -E '^\( cd .*(rm|ln)' install/doinst.sh | bash explodepkg $pkgstore/a/xfsprogs-+([^-])-+([^-])-+([^-]).t[gblx]z # 'ap' series packages: explodepkg $pkgstore/ap/dmidecode-+([^-])-+([^-])-+([^-]).t[gblx]z # 'l' series packages: #explodepkg $pkgstore/l/glibc-i18n-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/l/v4l-utils-+([^-])-+([^-])-+([^-]).t[gblx]z explodepkg $pkgstore/l/ncurses-+([^-])-+([^-])-+([^-]).t[gblx]z # set up symlinks for ncurses grep -E '^\( cd .*(rm|ln)' install/doinst.sh | bash # Install /usr/lib(64)/locale/en_US.utf8 from l/glibc-i18n. # bash-5.2 in a 'chroot' segfaults otherwise. #mkdir -vpm755 $TMPBUILD/initrd-tree/usr/lib${LIBDIRSUFFIX}/locale #cp -fav usr/lib${LIBDIRSUFFIX}/locale/en_US.utf8 $TMPBUILD/initrd-tree/usr/lib${LIBDIRSUFFIX}/locale/ # Add dmidecode: install -vpm755 usr/sbin/dmidecode $TMPBUILD/initrd-tree/sbin/ # Wholesale replacement of Busybox's MTD utilities, as the proper ones # have more features. These aren't required for booting the OS, but may # prove useful during troubleshooting or onboarding new Hardware Models: pushd $TMPBUILD/pkg-extract/special-handling explodepkg $pkgstore/a/mtd-utils-+([^-])-+([^-])-+([^-]).t[gblx]z cp -fav usr/libexec $TMPBUILD/initrd-tree/usr/ pushd usr/sbin for mtdutil in * ; do rm -fv $TMPBUILD/initrd-tree/sbin/$mtdutil install -vpm755 $mtdutil $TMPBUILD/initrd-tree/sbin/ done popd popd # Replace 'readlink' from BusyBox with the coreutils version: rm -f $TMPBUILD/initrd-tree/bin/readlink install -vpm755 bin/readlink $TMPBUILD/initrd-tree/bin/ # Replace 'mount' with util-linux's version: #rm -f $TMPBUILD/initrd-tree/bin/mount #install -vpm755 bin/mount $TMPBUILD/initrd-tree/bin/ # Replace 'lspci' from Busybox with the 'pciutils' version, and 'lsusb' from the 'usbutils' package. # This is because Busybox's doesn't consult the hardware ID data, which we use to conditionally # load Kernel modules within the OS InitRD: rm -f $TMPBUILD/initrd-tree/bin/ls{pci,usb} install -vpm755 usr/bin/ls{pci,usb} $TMPBUILD/initrd-tree/bin/ # Add pci.ids and usb.ids from the 'a/hwdata' package: mkdir -vpm755 $TMPBUILD/initrd-tree/usr/share/hwdata install -vpm644 usr/share/hwdata/{pci.ids,usb.ids} \ $TMPBUILD/initrd-tree/usr/share/hwdata/ gzip -9v $TMPBUILD/initrd-tree/usr/share/hwdata/* # Install /usr/bin/ir-keytable from 'l/v4l-utils' package: # since udev calls it, and soft errors if unavailable: mkdir -vpm755 $TMPBUILD/initrd-tree/usr/bin install -vpm755 usr/bin/ir-keytable $TMPBUILD/initrd-tree/usr/bin/ # Install libtinfo from ncurses: mkdir -vpm755 $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX} cp -fav lib${LIBDIRSUFFIX}/libtinfo*.so* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/ # Install lsblk and its dependencies from the a/util-linux package: # This is used by the 'await_device' to find labeled file systems. cp -fav bin/lsblk $TMPBUILD/initrd-tree/bin/ cp -fav lib${LIBDIRSUFFIX}/libmount.so.* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/ cp -fav lib${LIBDIRSUFFIX}/libsmartcols.so.* $TMPBUILD/initrd-tree/lib${LIBDIRSUFFIX}/ # Support custom keymaps: install -vpm644 /usr/share/mkinitrd/keymaps.tar.gz $TMPBUILD/initrd-tree/etc/ # These are added by Slackware's 'mkinitrd' if these modules are required. # We'll add them as standard, since we bundle the modules in the generic # initrd. install -Dvpm755 sbin/{xfs_repair,jfs_fsck} -t $TMPBUILD/initrd-tree/sbin/ # Use the 'bash' shell instead of busybox, as Slackware ARM uses the # richer feature set to make the module loader scripts more succinct: rm -f $TMPBUILD/initrd-tree/bin/bash # is a symlink to busybox # /init needs to use bash as we use some of the extended features: sed -i 's?#!/bin/ash?#!/bin/bash?g' $TMPBUILD/initrd-tree/init install -vpm755 bin/bash* $TMPBUILD/initrd-tree/bin/bash # Helper to wait for the root device to become available: sed -i '\?^sleep \$WAIT*? a\. /await_device' $TMPBUILD/initrd-tree/init || exit 1 install -vpm755 $CWD/SlkOS-initrd-overlay/await_device $TMPBUILD/initrd-tree/ # Support execution of a function prior to switching into the OS proper: # This could be defined within a Hardware Model's Kernel Module Loader helper # script, or perhaps within the /boot/local/load_kernel_modules.post. # This is the last chance before the OS proper boots, and it's post software RAID # et al initialisation. sed -i '\?exec switch_root ?i\fnexists hwm_hook_pre_switch_root && hwm_hook_pre_switch_root' $TMPBUILD/initrd-tree/init || exit 1 sed -i '\?exec switch_root ?i\fnexists hook_pre_switch_root && hook_pre_switch_root' $TMPBUILD/initrd-tree/init || exit 1 # Wrap reboot to call the reboot binary with -f(orce). This is required because the # OS environment isn't fully established: # This wraps the binary because /usr/local/sbin is ahead of /sbin in $PATH mkdir -vpm755 $TMPBUILD/initrd-tree/usr/local/sbin echo "/sbin/reboot -f" > $TMPBUILD/initrd-tree/usr/local/sbin/reboot chmod 755 $TMPBUILD/initrd-tree/usr/local/sbin/reboot popd # Use 'mkinitrd' to create a default environment: cd $TMPBUILD echo "Calling mkinitrd: creating a default Slackware initrd environment" # Note: '-C luksdummy' is to enable mkinitrd to install the appropriate # libraries and tools into the initrd. No LUKS config is shipped by default. MKINITRD_ALLOWEXEC=yes \ mkinitrd \ -R \ -L \ -u \ -C luksdummy \ -k $VERSION-$SLKKERNELARCH \ -s $TMPBUILD/initrd-tree \ -o $TMPBUILD/initrdtmp.gz # Sanity check that mkinitrd created some output: [ ! -f $TMPBUILD/initrdtmp.gz ] && { read -p "ERROR: creation of temporary Initial RAM disk failed" exit 1 ;} # Switch to that new environment. # At this stage, we've # 1. Unpacked the standard Slackware initrd environment that's packaged # within the a/mkinitrd package # 2. Added 'bash' and a library from 'ncurses' to that environment # 3. Used the mkinitrd tool to populate that enviromnemt with the default # set of runtime libraries, taken from the host build system. # 4. Now we're going to switch to that new environment and continue # populating it to become the generic ARM OS InitRD. mv -fv $TMPBUILD/initrd-tree{,.orig} mkdir -vpm755 $TMPBUILD/initrd-tree cd $TMPBUILD/initrd-tree # Unpack the newly built initrd image into the fresh initrd root fs: zcat $TMPBUILD/initrdtmp.gz | cpio -di echo "Copying Kernel modules into OS InitRD" rm -rf lib/modules # purge what 'mkinitrd' populated # Copy the indexes, etc. (everything other than the Kernel modules and the build/source symlinks): mkdir -vpm755 lib/modules/$VERSION-$SLKKERNELARCH/kernel #cp -fa $PKG/lib/modules/$VERSION-$SLKKERNELARCH/!(build|kernel|source) lib/modules/$VERSION-$SLKKERNELARCH/ cp -fa $PKG/lib/modules/$VERSION-$SLKKERNELARCH/modules.{order,builtin*} lib/modules/$VERSION-$SLKKERNELARCH/ # Copy the Kernel module directories containing the major components: pushd $PKG/lib/modules/$VERSION-$SLKKERNELARCH/kernel grep -Ev '^#|^$' ${KMODINCLUDELIST} | tar --wildcards -pvvcf - -T- | tar -C${TMPBUILD}/initrd-tree/lib/modules/$VERSION-$SLKKERNELARCH/kernel/ -pxf - popd # Slim down the modules within the initrd by removing unnecessary # major sub systems or drivers for hardware that is not required during # the initial boot. # There will be far more that are also surplus to requirements but I'm # trying to strike a balance between size and enabling the community to # more easily light up Slackware AArch64 onto new platforms. # . $CWD/scripts/slim-kmods-initrd || exit 1 echo "Compressing initrd's Kernel modules with xz -e9 -- this will take 10-15 mins.." #time find ./lib/modules -type f -name "*.ko" -exec xz --threads $(( $(nproc) -1 )) -ze9f -C crc32 {} \; time find ./lib/modules -type f -name "*.ko" -exec xz $XZ_OPTS {} \; # Fix any broken symlinks post compression: for i in $(find ./lib/modules -type l -name "*.ko") ; do ln -vfs $( readlink $i ).xz $i.xz ; rm -fv $i ; done # Install some tools to help when onboarding Slackware ARM to new Hardware Models. mkdir -vpm755 tools install -vpm755 $CWD/SlkOS-initrd-overlay/tools/* tools/ # Install the Slackware ARM Hardware Model Discovery tool: # Into the OS InitRD: install -vpm755 $CWD/SlkOS-initrd-overlay/sbin/slk-hwm-discover sbin/ # and into the OS a/kernel_armvN package: mkdir -vpm755 $PKG/sbin install -vpm755 $CWD/SlkOS-initrd-overlay/sbin/slk-hwm-discover $PKG/sbin/ # Kernel Module loader for Slackware AArch64. This loads a base set of # platform modules generally useful on all SoCs, and at boot time # loads specific SoC modules for the host platform. # If you want to add support for a new platform, please look at this # script and give mozes@slackware.com a diff. install -vpm755 $CWD/SlkOS-initrd-overlay/load_kernel_modules . # Install the board support scripts: mkdir -vpm755 load_kernel_modules.scr/platform/$SLKPORTARCH install -vpm755 $CWD/SlkOS-initrd-overlay/load_kernel_modules.scr/platform/$SLKPORTARCH/* \ load_kernel_modules.scr/platform/$SLKPORTARCH/ # Kernel module modprobe configuration files. This is principally to enable # module black lists: # At run time the /load_kernel_modules moves any modprobe config files it finds # into the OS InitRD's /etc/modprobe.d/ prior to the modules being loaded. mkdir -vpm755 etc/modprobe.d usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d if [ -d $CWD/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d ]; then # note: the Installer builder sets all files to chmod 644 and dirs to 755. # if we need any other perms we'll need to be more discerning within the Installer builder. install -vpm644 \ $CWD/SlkOS-initrd-overlay/usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d/* \ usr/share/hwm-configure/platform/$SLKPORTARCH/modprobe.d/ fi # Add them into the Slackware Kernel package: # Not yet since there's no way to have modprobe discriminate at the Hardware Model level. # Some Hardware Models share IP cores, and we might not want the same settings for # Each Hardware model. # Presently we'll only handle this within the Installer and OS InitRD. If we need to # sync with the /etc/modprobe.d/ within the Slackware OS, we'll figure it out later. # We also might want to have a user-maintained /etc/modprobe.d/ synced with the InitRD # as a way for the user to control it. # I could probably have the installer populate the modprobe.d configs but we still # need to manage the updates somehow. # Food for thought.. #mkdir -vpm755 $PKG/etc/modprobe.d #install -vpm644 $CWD/SlkOS-initrd-overlay/etc/modprobe.conf/* $PKG/etc/modprobe.d/ # Walk the host architecture, calling the helper scripts to # perform any Hardware Model specific actions. # Presently this is to install firmware into the OS InitRD's /lib/firmware # for Hardware Models. if [ -d $CWD/platform/$SLKPORTARCH ]; then for helper in $( find $CWD/platform/$SLKPORTARCH -type f -mindepth 1 -maxdepth 1 ) ; do echo "Executing Kernel Build helper for ${helper##*/}" . $helper done fi # Generic initrd configuration: > rootdev # both are controlled by the Kernel cmdline parameters since > rootfs # this is a generic platform initrd. echo 2 > wait-for-root # media spinup delay echo "/boot/initrd-$SLKKERNELARCH.gz" > initrd-name rm -f command_line # it was a temporary build - useless info # Wipe dummy LUKS config: > luksdev > lukskey rm -f lukstrim # just incase one ever appears! # Shipping the Software RAID configuration of a build machine # doesn't make sense. /init tries to set up Software RAID itself # but users can also use the os-initrd-mgr tool to manage the # addition and removal of the OS's /etc/mdadm.conf. rm -f etc/mdadm.conf # Update the indexes so we can boot this baby: echo "Updating linker cache and Kernel module maps...." ldconfig -r. depmod -b. $VERSION-$SLKKERNELARCH # Pack into initramfs format: find . | cpio -o -H newc | gzip -9 > $TMPBUILD/initrd-$SLKKERNELARCH.gz # This works, but we need to remove the.gz suffixes within this build script and retest with Linux 6.1: #os-initrd also needs to pack with lzma - it can already identify and decompress gz or xz. #find . | cpio -o -H newc | xz --threads $(( $(nproc) -1 )) -vz9f -C crc32 > $TMPBUILD/initrd-$SLKKERNELARCH.gz # Store the size of the initrd uncompressed, so that the # /usr/sbin/os-initrd-mgr knows how much temp space to allocate # when repacking the OS initrd to include any user local additions: cat << EOF > $PKG/boot/.boot_details # Build host: $( uname -n ) # Kernel build date: $( date -u ) # # This file was created originally by source/k/kernel.SlackBuild # during the Kernel package build process, and potentially updated # by /usr/sbin/os-initrd-mgr. # # # Do not edit this file by hand! # # # Size of the OS InitRD in bytes. This is used for os-initrd-mgr to # determine whether it can safely unpack the initrd. initrdsize=$( du -sb . | awk '{print $1}' ) # ARM architecture version. This allows os-initrd-mgr to rebuild # the initrd via the symlink /boot/initrd-armvN. # armv7 = "Slackware ARM" - 32bit/ARM32 # armv8 = "Slackware AArch64" - 64bit/ARM64 platform=$SLKKERNELARCH # Slackware Kernel version: slkkernel=$VERSION-$SLKKERNELARCH EOF # Add the sample scripts: install -Dvpm644 $CWD/boot-skeleton/local/* -t $PKG/boot/local/ # Add the Hardware Model post Kernel package installation helper scripts. # There aren't any for ARM32 presently: [ "$SLKPORTARCH" = "aarch64" ] && { install -Dvpm644 $CWD/boot-skeleton/platform/aarch64/helper/README.txt -t $PKG/boot/platform/aarch64/helper/ # We may store other types of helper scripts here in the future, so # we'll take only our 'kernel' helpers: install -Dvpm755 $CWD/boot-skeleton/platform/aarch64/helper/pkg-kernel-* -t $PKG/boot/platform/aarch64/helper/ } # Add the OS Initrd Manager: install -Dvpm755 $CWD/sources/os-initrd-mgr -t $PKG/usr/sbin/ mkdir -vpm755 $PKG/usr/man/man8 pod2man \ --section=8 \ --release="$( grep -E ' Date.*:' $CWD/sources/os-initrd-mgr | awk -F: '{ print $2 }' )" \ --center=' ' \ --date="os-initrd-mgr Version $( grep -E ' Version.*: ' $CWD/sources/os-initrd-mgr | awk -F: '{ print $2 }' )" \ $CWD/sources/os-initrd-mgr.pod 2>&1 | gzip -9f > $PKG/usr/man/man8/os-initrd-mgr.8.gz # Add the sample os-initrd-mgr config file: install -Dvpm644 $CWD/sources/os-initrd-mgr.conf.sample -t $PKG/etc/ # Store the standard gzipped initial RAM disk, plus its U-Boot format counterpart: # # 1. Within the 'slackware-current/kernels' directory. # # When building patch packages, we never provide an updated version of this file outside of the # package archive. This is because files in the '/kernels' directory are generally for # use with the Slackware installer image, and we normally don't update those once the # Slackware version is released (as they'd be different versions to those in the main # 'slackware/' tree). #if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then if [ "$SLACKPATCHING" = "no" ]; then for imgtype in {,u}initrd ; do [ -f $TMPBUILD/${imgtype}-$SLKKERNELARCH.gz ] && \ install -vpm644 $TMPBUILD/${imgtype}-$SLKKERNELARCH.gz \ $rootdir/kernels/$SLKKERNELARCH/${imgtype}-$SLKKERNELARCH done fi # 2. Within $PKG/boot # # This allows devices whose boot loader can read the partition where /boot resides # (all Directly Integrated Hardware Model support): [ -f $TMPBUILD/uinitrd-$SLKKERNELARCH ] && \ install -vpm644 $TMPBUILD/uinitrd-$SLKKERNELARCH $PKG/boot/uinitrd-$SLKKERNELARCH-$VERSION # The gzipped compressed cpio version: install -vpm644 $TMPBUILD/initrd-$SLKKERNELARCH.gz $PKG/boot/initrd-$SLKKERNELARCH-$VERSION # Create symlinks to enable static boot loader configuration: # (having version numbers would necessitate a boot loader change with every # Kernel package release): ( cd $PKG/boot for imgtype in {,u}initrd ; do [ -f $imgtype-$SLKKERNELARCH-$VERSION ] && \ ln -vfs $imgtype-$SLKKERNELARCH-$VERSION $imgtype-$SLKKERNELARCH done ) # It's nice to have this final touch (pun intended): ##if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then #if [ "$SLACKPATCHING" = "no" ]; then # ( cd $rootdir/kernels/$SLKKERNELARCH/ # for imgtype in {,z,u}Image ; do # [ -f $imgtype-$SLKKERNELARCH ] && \ # touch -r $imgtype-$SLKKERNELARCH * $PKG/boot/* # done ) #fi # Compile the Device Tree Source (DTS) files into Device Tree Blobs (DTB): # This file is for the 'Flattened Device Tree' technology. # For the generic 'armv7' kernels, we have no way of knowing which DTB file # the user will require, so we have to ship them all for each architecture. # mkdir -vpm755 $PKG/{install,boot/dtb-$VERSION} ln -rvfs $PKG/boot/dtb-$VERSION $PKG/boot/dtb # Ensure that we're in the correct directory to build the DTB files. cd $KERNELSRCDIR/linux-$VERSION && make ARCH=$LINUXKERNELARCH dtbs || failmake # Install them to a temporary directory. The make install # creates a 'dtbs' directory within the specified path. make INSTALL_PATH=$TMPBUILD dtbs_install || failmake # Copy the extra ones that are not yet in the mainline kernel. These are only for # armv7: # This was for an experiment where I was using a forked Kernel tree. #if [ "$SLKKERNELARCH" = "armv7" ]; then # echo "Adding extra DTBs from $CWD/sources/extra-dtb/ (if any exist)" # cp -fav $CWD/sources/extra-dtb/*.dtb $KERNELSRCDIR/linux-$VERSION/arch/$LINUXKERNELARCH/boot/dts/ #fi # Install DTB's into the package: #install -vpm644 $KERNELSRCDIR/linux-$VERSION/arch/$LINUXKERNELARCH/boot/dts/*.dtb $PKG/boot/dtb-$VERSION/ # AArch64 groups the DTBs by platform type, unlike ARM where they're in a # flat level directory structure. # The directory structure is: $TMPBUILD/dtbs/5.10.21-armv8 cp -fa $TMPBUILD/dtbs/*/* $PKG/boot/dtb-$VERSION/ || failinstall # Install copies into the 'kernels' directory so that they can be easily # available for tftp booting: # We don't version the DTB files inside the '/kernels' directory because # the kernel + initrd files are not versioned here since this dir is not # packaged/version managed. #if [ "$SLACKPATCHING" = "no" -a ! -d "${PKGSTORE_OVERRIDE}" ]; then if [ "$SLACKPATCHING" = "no" ]; then rm -rf $rootdir/kernels/$SLKKERNELARCH/dtb mkdir -vpm755 $rootdir/kernels/$SLKKERNELARCH/dtb cp -fa $TMPBUILD/dtbs/*/* $rootdir/kernels/$SLKKERNELARCH/dtb/ || failinstall #install -vpm644 -oroot -groot $PKG/boot/dtb-$VERSION/* $rootdir/kernels/$SLKKERNELARCH/dtb/ fi ############################################################################### # Build the base 'a/kernel' package: ############################################################################### echo "*****************************************************************" echo "Building base package slackware/a/$SLACKPACKAGE" echo "*****************************************************************" # Replace version number with a _ so it doesn't get confused with # the package name. # This is incase we're using any '-rc' releases. export VERSION="$( echo $VERSION | sed 's?-??g' )" cd $PKG # This is a symlink to where the kernel was compiled # We wipe these and create new ones pointing to /usr/src # (our kernels were compiled in a temporary location, so the symlink would be broken) # The symlinks looked like this: # /lib/modules//build -> /root/tmp/build-kernel_armv7/linux-5.15.19 # Why don't we just make the symlink using the existing variables? # That's because at the time of writing I'm taking this from the old kernel-modules.SlackBuild # and my guess is that at some points, the dir name might not be what we expected. pushd lib/modules/* LINKLOC=$( find . -name source -printf "%l\n" | rev | cut -d/ -f1 | rev ) rm -rf source ln -vfs ../../../usr/src/$LINKLOC source LINKLOC=$( find . -name build -printf "%l\n" | rev | cut -d/ -f1 | rev ) rm -rf build ln -vfs ../../../usr/src/$LINKLOC build popd # Update the dependencies list: # depmod -b $PKG $VERSION # Generate modules.dep files for each ARM architecture we have inside lib/modules. # This is legacy from when we had the all-in-one script, but I like it so it stays :-) find lib/modules -type d -mindepth 1 -maxdepth 1 -printf "%f\n" | xargs -i depmod {} -b. # Apply some of the generic Slackware packaging policies: slackslack # chown -R root:root, chmod -R og-w, slack644docs # If $PKGSTORE_OVERRIDE is set and exists as a directory, we'll switch # $PKGSTORE to it so that our packages are stored outside of the main tree. # This enables new Kernels to be tested more easily. # The PKGSERIES directories (a,d,k) should have already been created. [ -d "${PKGSTORE_OVERRIDE}" ] && PKGSTORE="${PKGSTORE_OVERRIDE}" # We need to pre-pend the symlink code to the main 'doinst.sh' since it requires the # versionless symlinks for /usr/sbin/os-initrd-mgr #makepkg -p -l y -c n $PKGSTORE/$PKGSERIES/$PKGNAM-$VERSION-$SLKPORTARCH-$BUILD.txz slackmp -p # run makepkg --prepend -l y -c n ############################################################################### # Build the 'd/kernel-headers' package: ############################################################################### # The headers are installed into the root of this package earlier # in the Kernel build process, so all we need here is to install the # slack-desc and set permissions. # Package information: export PKGNAM=kernel-headers export SLACKPACKAGE=$PKGNAM-$VERSION-$PKGARCH-$BUILD.txz echo "*****************************************************************" echo "Building package: $SLACKPACKAGE" echo "*****************************************************************" # Handle building within /patches: [ "$SLACKPATCHING" = "no" ] && export PKGSERIES=d # Enter package root: cd $TMPBUILD/package-kernel-headers || exit 1 # Install package description: install -vpm644 $CWD/slack-descs/kernel-headers install/slack-desc # Apply some of the generic Slackware packaging policies: slackslack # chown -R root:root, chmod -R og-w, slack644docs echo " + Running makepkg for 'kernel-headers'" slackmp # run makepkg ############################################################################### # Build the 'k/kernel-source' package: ############################################################################### # Package information: export PKGNAM=kernel-source export SLACKPACKAGE=$PKGNAM-$VERSION-$PKGARCH-$BUILD.txz echo "*****************************************************************" echo "Building package: $SLACKPACKAGE" echo "*****************************************************************" # Handle building within /patches: [ "$SLACKPATCHING" = "no" ] && export PKGSERIES=k # Move the Kernel source into a directory into which we can package it: cd $KERNELSRCDIR # Prepare the package framework: mkdir -vpm755 $TMPBUILD/package-kernel-source/{install,usr/src} # Move the Linux source into our packaging directory: # echo "Copying Linux source for packaging..." # We won't do this since it takes longer and during development # I never need any of the assets that are removed by the packaging process. # Reversion: actually, I started using it all the time so we'll copy them now. # Plus this breaks when using the '--srcdir' option to kernel.SlackBuild. cp -fa linux-$VERSION $TMPBUILD/package-kernel-source/usr/src/ || exit 1 #mv -fv linux-$VERSION $TMPBUILD/package-kernel-source/usr/src/ || exit 1 cd $TMPBUILD/package-kernel-source/usr/src || exit 1 # Ensure that the linux dir name matches the $VERSION of the package so that # in the a/kernel package, the /lib/modules/*/{build,source} # symlinks are correct. ln -vfs linux-$VERSION linux cd linux || exit 1 # Prepare for packaging: echo " + Cleaning up the source tree" make ARCH=$LINUXKERNELARCH clean # Make sure header files aren't missing: make ARCH=$LINUXKERNELARCH prepare # Don't package the kernel in the sources: find . -name "*Image" -exec rm "{}" \; # No need for these: rm -fv .config.old .version find . -name "*.cmd" -exec rm -f "{}" \; rm -v .*.d find . -name '.gitignore' -print0 | xargs -0 rm -rf find . -name '.tmp*' -print0 | xargs -0 rm -rf # Remove any ELF (non-eBPF) binaries that are not executable: find . -type f -perm 0644 | xargs file | grep ELF | grep -v eBPF | grep stripped | cut -f 1 -d : | while read elf_binary ; do rm -fv $elf_binary done # Strip any remaining binaries: find . | xargs file | grep -e "executable" -e "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null # Install package description: cd $TMPBUILD/package-kernel-source install -vpm644 $CWD/slack-descs/kernel-source install/slack-desc # Apply some of the generic Slackware packaging policies: slackslack # chown -R root:root, chmod -R og-w, slack644docs echo " + Running makepkg for 'kernel-source'" slackmp # run makepkg #EOF