******************************************************************************** *** BUILD SCRIPT FOR RASPBERRY PI 64-BIT KERNEL BUILD *** *** Allan's Workshop *** *** https://www.drassal.net/wp/raspberry-pi-64-bit-linux-kernel-rebuild *** *** Revised 2025-01-12 *** ******************************************************************************** *** THIS SCRIPT IS NOT INTENDED TO BE DIRECTLY EXECUTED *** COPY/PASTE EACH SET OF COMMANDS IN SEQUENCE *** create a Raspberry Pi micro sd card *** replace /dev/sda with the micro sd card device *** for example change /dev/target to /dev/sda *** be careful and do not mistake the device *** for exmaple change /dev/targetpartition to /dev/sda1 *** be sure the device and all partitions are unmounted first sudo umount /dev/targetpartition *** copy the image onto the micro sd card xzcat /var/datadisk/raspberrypi/2024-11-19-raspios-bookworm-arm64-full.img.xz | sudo dd of=/dev/target *** flush the buffer to ensure all data is written to the micro sd card sync *** INSERT THE MICRO SD CARD INTO THE RASPBERRY PI *** POWER UP THE RASPBERRY PI *** COMPLETE THE INITIAL RASPBERRY PI SETUP NOW *** COMPLETE ANY SETUP REQUIRED TO ESTABLISH AN INTERNET CONNECTION *** ENABLE SSH NOW (if desired) *** IF INTERNET CONNECTION IS NOT POSSIBLE THEN PRE DOWNLOAD THE RASPBERRY PI KERNEL SOURCES FROM GITHUB *** git clone --depth=1 https://github.com/raspberrypi/linux *** ssh into the raspberry pi *** or open a terminal on the raspberry pi *** change to super user sudo su *** SETUP ENVIORNMENT VARIABLES NOW_YMDHMS=$(date +"%Y%m%d%H%M%S") NOW_YMD=$(date +"%Y%m%d") DATESTAMP=${NOW_YMD} WORKROOT=/media/pi/e65e2c06-9254-4d71-b75e-3e407c807acf WORKDIR=${WORKROOT}/kernel_build_${DATESTAMP} BOOTDIR=/boot/firmware KERNELMODULESDIR=/lib/modules *** prepare the raspberry pi directory rm -rf ${WORKDIR} mkdir ${WORKDIR} cd ${WORKDIR} *** install required tools apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev *** download and prepare the kernel sources on the raspberry pi *** get the current kernel rm -rf ${WORKDIR}/linux git clone --depth=1 https://github.com/raspberrypi/linux *** set the kernel version *** parse and display the version #kernel version found in kernel Makefile, at the top (VERSION, PATCHLEVEL, SUBLEVEL) filename="${WORKDIR}/linux/Makefile" KERNEL_VERSION=$(grep -m 1 VERSION $filename | sed 's/^.*= //g') KERNEL_VERSION=${KERNEL_VERSION}. KERNEL_VERSION=${KERNEL_VERSION}$(grep -m 1 PATCHLEVEL $filename | sed 's/^.*= //g') KERNEL_VERSION=${KERNEL_VERSION}. KERNEL_VERSION=${KERNEL_VERSION}$(grep -m 1 SUBLEVEL $filename | sed 's/^.*= //g') echo "KERNEL_VERSION="${KERNEL_VERSION} *** archive downloaded files for possible use later tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux . *** ON THE RASPBERRY PI (or in the SSH session) *** configure and build kernel (kernel8) *** for the following models #Architecture 64-bit #Models # Raspberry Pi 3 # Raspberry Pi Compute Module 3 # Raspberry Pi 3+ # Raspberry Pi Compute Module 3+ # Raspberry Pi Zero 2 W # Raspberry Pi 4 # Raspberry Pi 400 # Raspberry Pi Compute Module 4 # Raspberry Pi Compute Module 4S *** configure the build cd ${WORKDIR}/linux KERNEL=kernel8 make bcm2711_defconfig *** must add btrfs filesystem support to as built-in, not module make menuconfig *** File systems -> Btrfs filesystem support *** change M to y *** Customize the kernel version using LOCALVERSION #To prevent the kernel from overwriting existing modules in /lib/modules and to clarify that you run your own kernel in uname output, adjust LOCALVERSION. #To adjust LOCALVERSION, change the following line in .config: #CONFIG_LOCALVERSION="-v7l-MY_CUSTOM_KERNEL" *** Run the following commands to build a 64-bit kernel: make -j6 Image.gz modules dtbs *** prepare the kernel modules rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules make -j6 INSTALL_MOD_PATH=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules modules_install *** archive the modules for later use tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules/lib/modules/ . *** archive the 64-bit kernel: *** archive the kernel and kernel config rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL} mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL} cp arch/arm64/boot/Image.gz ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/${KERNEL}.img cp .config ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/${KERNEL}.config tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/ . *** archive backup the overlays: *** archive the overlays rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb cp arch/arm64/boot/dts/broadcom/*.dtb ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/ mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays cp arch/arm64/boot/dts/overlays/*.dtb* ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays/ cp arch/arm64/boot/dts/overlays/README ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays/ tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/ . *** ON THE RASPBERRY PI (or in the SSH session) *** configure and build kernel (kernel_2712) *** for the following models #Architecture 64-bit #Models # Raspberry Pi 5 *** configure the build cd ${WORKDIR}/linux KERNEL=kernel_2712 make bcm2712_defconfig *** must add btrfs filesystem support to as built-in, not module make menuconfig *** File systems -> Btrfs filesystem support *** change M to y *** Customize the kernel version using LOCALVERSION #To prevent the kernel from overwriting existing modules in /lib/modules and to clarify that you run your own kernel in uname output, adjust LOCALVERSION. #To adjust LOCALVERSION, change the following line in .config: #CONFIG_LOCALVERSION="-v7l-MY_CUSTOM_KERNEL" *** Run the following commands to build a 64-bit kernel: make -j6 Image.gz modules dtbs *** prepare the kernel modules rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules make -j6 INSTALL_MOD_PATH=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules modules_install *** archive the modules for later use tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules/lib/modules/ . *** archive the 64-bit kernel: *** archive the kernel and kernel config rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL} mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL} cp arch/arm64/boot/Image.gz ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/${KERNEL}.img cp .config ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/${KERNEL}.config tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}/ . *** archive backup the overlays: *** archive the overlays rm -rf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb cp arch/arm64/boot/dts/broadcom/*.dtb ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/ mkdir -p ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays cp arch/arm64/boot/dts/overlays/*.dtb* ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays/ cp arch/arm64/boot/dts/overlays/README ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/overlays/ tar -jcvpf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb_${DATESTAMP}.tar.bz2 --directory=${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb/ . *** at this point new kernel and kernel modules have been created *** next step is to update the sd card with the new kernel *** backup the current bootfs if needed tar -jcvpf ${WORKDIR}/bootfs_${DATESTAMP}.tar.bz2 --directory=${BOOTDIR} . *** restore the bootfs from backup if needed *** first blow away the bootfs rm -rf ${BOOTDIR}/* *** verify the current bootfs is empty ls -la ${BOOTDIR} *** next, restore the bootfs from backup tar xjf ${WORKDIR}/bootfs_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} *** verify the current bootfs is now populated ls -la ${BOOTDIR} *** copy the new kernel to the bootfs *** for kernel8 (raspberry pi 3, 3a, 3a+, 3b, 3b+, 4, cm4, 400, zero, 2w KERNEL=kernel8 tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} ./${KERNEL}.img *** dtb files should be same for all kernels tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} *** optional but recommended to retain a copy of the kernel configuration tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} ./${KERNEL}.config *** copy the new kernel to the bootfs *** for kernel_2712 (raspberry pi 5) KERNEL=kernel_2712 tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} ./${KERNEL}.img *** dtb files should be same for all kernels #tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_dtb_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} *** optional but recommended to retain a copy of the kernel configuration tar xjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_${DATESTAMP}.tar.bz2 -C ${BOOTDIR} ./${KERNEL}.config *** copy the kernel modules to the rootfs *** blow away the current modules if desired rm -rf ${KERNELMODULESDIR}/* *** copy kernel modules to the rootfs *** for kernel8 (raspberry pi 3, 3a, 3a+, 3b, 3b+, 4, cm4, 400, zero, 2w KERNEL=kernel8 tar xpjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules_${DATESTAMP}.tar.bz2 -C ${KERNELMODULESDIR} *** copy kernel modules to the rootfs *** for kernel_2712 (raspberry pi 5) KERNEL=kernel_2712 tar xpjf ${WORKDIR}/linux_${KERNEL_VERSION}_${KERNEL}_modules_${DATESTAMP}.tar.bz2 -C ${KERNELMODULESDIR} *** run the below command after restart to verify the new kernel is running cat /proc/version *** sample output below pi@raspberrypi:~ $ cat /proc/version Linux version 6.6.70-v8-16k+ (root@raspberrypi) (gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40) #2 SMP PREEMPT Sun Jan 12 03:38:56 JST 2025