#!/bin/bash # 2022-10-15 KERNEL_DEFAULT=6.0 OUTFOLDER=$1 KERNEL_MAIN=$2 KERNEL_PATCH=$3 KERNEL_RT=$4 PATCH_FILE= KERNEL= FINAL_FOLDER=$OUTFOLDER BASE_FOLDER=$FINAL_FOLDER SKIP_PACMAN=1 SKIP_TOOLCHAIN_CREATION=1 SKIP_ADD_FOLDER=0 SKIP_GRAB_KERNEL=0 SKIP_KERNEL_RT=1 SKIP_BUILD_KERNEL=0 SKIP_BUILD_FINAL=0 # # https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel # https://wiki.archlinux.org/title/Cross-compiling_tools_package_guidelines # https://ilyas-hamadouche.medium.com/creating-a-cross-platform-toolchain-for-raspberry-pi-4-5c626d908b9d # function header() { clear echo ">>> Toolchain Archlinux / RPi 4 ARM64 / Kernel" echo "--------------------------------------------------" echo ">> DATE : $CURRENT" echo ">> OUTFOLDER: $OUTFOLDER" echo ">> BRANCH : $BRANCH" echo ">> PATCH : $PATCH_FILE" echo ">> RT PATCH : $KERNEL_RT" echo ">> VERSION : $VERSION" echo ">> KERNEL : $KERNEL" echo "--------------------------------------------------" echo "" } function wait() { read -p "> [Press enter to continue] " } header echo "> Prepare things" # if kernel branch is not given, use default if [ -z "$KERNEL_MAIN" ]; then KERNEL_MAIN=$KERNEL_DEFAULT fi # if patch is given but file doesn't exist, remove it if [ ! -z "$KERNEL_PATCH" ]; then if [ ! -f "$KERNEL_PATCH" ]; then KERNEL_PATCH= else PATCH_FILE=$(basename $KERNEL_PATCH) fi fi # kernel branch/version MAIN=$KERNEL_MAIN BRANCH=rpi-$MAIN.y # use current date as base kernel folder CURRENT=$(date '+%Y-%m-%d') # folders OUTFOLDER=$BASE_FOLDER/$CURRENT header echo "> Create working folders" if [ ! -d "~/src" ]; then mkdir -p ~/src fi if [ ! -d "$OUTFOLDER" ]; then mkdir -p $OUTFOLDER fi cd $OUTFOLDER if [ ! -d "ctng" ]; then mkdir ctng fi cd $OUTFOLDER if [ ! -z "$PATCH_FILE" ]; then cp $KERNEL_PATCH $OUTFOLDER/$PATCH_FILE fi if [ "$SKIP_PACMAN" == "0" ]; then header echo "> Install crosstool-ng" wait sudo pacman -S --needed crosstool-ng fi if [ "$SKIP_TOOLCHAIN_CREATION" == "0" ]; then header echo "> Create toolchain for RPi 4" echo ">> Set 'Render the toolchain read-only' to false (uncheck)" wait ulimit -n 4096 now # # Make 1 changes: # 1. Allow extending the toolchain after it is created (by default, it is created as read-only): # Paths and misc options -> Render the toolchain read-only ->false # cd ctng ct-ng -j$(nproc) aarch64-rpi4-linux-gnu ct-ng -j$(nproc) menuconfig header # (path: ${HOME}/x-tools/aarch64-rpi4-linux-gnu) echo "> Build the toolchain" ct-ng -j$(nproc) build fi header echo "> Add toolchain path" cd $OUTFOLDER PATH=$PATH:~/x-tools/aarch64-rpi4-linux-gnu/bin if [ "$SKIP_ADD_FOLDER" == "0" ]; then header echo "> Add folders" wait sudo rm -rf build mkdir -p build/mnt/fat32/overlays mkdir -p build/mnt/ext4/opt/build/kernel/$CURRENT/$BRANCH fi if [ ! -z "$PATCH_FILE" ]; then cp $OUTFOLDER/$PATCH_FILE build/mnt/$PATCH_FILE fi if [ "$SKIP_GRAB_KERNEL" == "0" ]; then header echo "> Get kernel sources" rm -rf linux rm -rf $BRANCH git clone --branch $BRANCH --depth=1 https://github.com/raspberrypi/linux mv linux $BRANCH fi cd $BRANCH header echo "> Get exact kernel version" FILE=Makefile KVERSION=VERSION KPATCHLEVEL=PATCHLEVEL KSUBLEVEL=SUBLEVEL KEXTRAVERSION=EXTRAVERSION GET_VAR=$KVERSION && KVERSION=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true) GET_VAR=$KPATCHLEVEL && KPATCHLEVEL=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true) GET_VAR=$KSUBLEVEL && KSUBLEVEL=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true) GET_VAR=$KEXTRAVERSION && KEXTRAVERSION=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true) VERSION=$KVERSION.$KPATCHLEVEL.$KSUBLEVEL if [ "$SKIP_BUILD_KERNEL" == "0" ]; then header if [ "$SKIP_KERNEL_RT" == "0" ]; then echo "> Apply RT patchs" wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/$MAIN/patch-$MAIN-$KERNEL_RT.patch.gz if [ ! -f patch-$MAIN-$KERNEL_RT.patch.gz ]; then echo ">> No Kernel RT patch found... Not appying !" wait else gzip -cd patch-$MAIN-$KERNEL_RT.patch.gz | patch -p1 --verbose fi fi header echo "> Generate default config" KERNEL=kernel8 env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- bcm2711_defconfig header echo "> Disable Debug Infos" env PATH=$PATH scripts/config --disable DEBUG_INFO header echo "> Backup config" cp -f .config .config.original if [ ! -z "$PATCH_FILE" ]; then header echo "> Apply config patch" cp $OUTFOLDER/$PATCH_FILE $PATCH_FILE patch < $OUTFOLDER/$PATCH_FILE fi # setup kernel config and generate diff patch from original # or patch default config with defined patch header echo "> Generate config" echo ">> If you specified patch, you may save/exit only" echo ">> Feel free to adjust settings too..." wait env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- menuconfig if [ ! -f ".config" ]; then header echo "> !!! No .config (menuconfig) found!" echo "> !!! Abort!" exit 1 fi header echo "> Create config patch from original for current version" diff -u .config.original .config > $OUTFOLDER/kernel_config_patch_$VERSION.patch header echo "> Disable Debug Info" wait env PATH=$PATH scripts/config --disable DEBUG_INFO header echo "> Compile kernel" wait env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- Image modules dtbs header echo "> Install modules" env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- INSTALL_MOD_PATH=../build/mnt/ext4 modules_install else KERNEL=kernel8 fi KERNEL=$KERNEL-$VERSION-v8+ header echo "> Copy files" wait sudo cp arch/arm64/boot/Image ../build/mnt/fat32/$KERNEL.img sudo cp arch/arm64/boot/dts/broadcom/*.dtb ../build/mnt/fat32/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* ../build/mnt/fat32/overlays/ sudo cp arch/arm64/boot/dts/overlays/README ../build/mnt/fat32/overlays/ header echo "> Adjust permissions" wait cd $OUTFOLDER sudo chmod -R 0755 build/mnt/fat32/ header echo "> Copy kernel source" cd $OUTFOLDER sudo mkdir -p build/mnt/ext4/opt/build/kernel/$CURRENT/$BRANCH sudo cp -r $BRANCH build/mnt/ext4/opt/build/kernel/$CURRENT/ header echo "> Remove symlinks..." wait cd $OUTFOLDER cd build/mnt/ext4/lib/modules/$VERSION-v8+/ sudo rm build sudo rm source header echo "> Create post-install script..." cd $OUTFOLDER sudo chown -R 1000:1000 build cd build/mnt/ rm -f install.sh touch install.sh tee -a install.sh <>> Installation of kernel [$KERNEL]" echo "> Setup permissions (fat32)" chmod -R 0755 fat32/ echo "> Setup owner (root)" chown -R root:root fat32/ chown -R root:root ext4/ echo "> Copy files (fat32, ext4)" cp -rf fat32/. /boot/ cp -rf ext4/lib/. /lib/ cp -rf ext4/opt/. /opt/ echo "> Symlink kernel source to modules ($VERSION-v8+)" rm -f /lib/modules/$VERSION-v8+/build rm -f /lib/modules/$VERSION-v8+/source ln -s /opt/build/kernel/$CURRENT/$BRANCH /lib/modules/$VERSION-v8+/build ln -s /opt/build/kernel/$CURRENT/$BRANCH /lib/modules/$VERSION-v8+/source echo "> Add kernel line (as disabled) to config.txt" echo '#kernel=$KERNEL.img' >> /boot/config.txt echo "> Done!" EOF chmod +x install.sh header echo "> Adjust rights" wait cd $OUTFOLDER sudo chown -R root:root build if [ "$SKIP_BUILD_FINAL" == "0" ]; then header echo "> Build archive" cd $OUTFOLDER/build/mnt/ sudo tar -cf $OUTFOLDER/rpi_kernel_arm64_$VERSION.tar . sudo chown 1000:1000 $OUTFOLDER/rpi_kernel_arm64_$VERSION.tar header echo "> Compress archive" cd $OUTFOLDER sudo pigz --force --best rpi_kernel_arm64_$VERSION.tar sudo chown 1000:1000 rpi_kernel_arm64_$VERSION.tar.gz fi header echo "> Create install script" rm -f install.sh touch install.sh tee -a install.sh <>> Extraction of kernel [$KERNEL]" echo "> Unzip archive" pigz -d rpi_kernel_arm64_$VERSION.tar.gz chown root:root rpi_kernel_arm64_$VERSION.tar echo "> Untar archive" tar -xf rpi_kernel_arm64_$VERSION.tar echo "> Set install script as root/executable" chown root:root install.sh chmod +x install.sh echo "> Proceed to install kernel with: [bash install.sh]" echo "> Done!" EOF chmod +x install.sh header echo "> Done!" exit 0