Skip to content

Build an RPi4 64bit Kernel on your crossdev PC

sakaki edited this page Jun 25, 2020 · 2 revisions

Build a 64-bit kernel for your Raspberry Pi 4 in minutes, using your crossdev PC!

For instructions on building an RPi3 compatible kernel instead, please see my instructions here.

Prerequisites

This guide assumes that you have already set up crossdev on your PC (and then used it to create a stable-branch aarch64-unknown-linux-gnu toolchain), per these instructions. So, if you haven't yet, please do this first, before proceeding.

Building an RPi4-Compatible 64-bit Kernel

First, we need to download some kernel sources. The official Raspberry Pi Linux kernel tree (which may be found here) now contains support for arm64 kernels. Decide which kernel version branch you want to build by browsing on GitHub, and then download a shallow copy of this to your PC (users with sufficient bandwidth and disk space may of course clone the entire tree, and then choose the desired branch locally, but the following approach is much faster). I recommend using at least version rpi-5.4.y to get the most up-to-date changes; in the below, I'll assume you want to use version rpi-5.4.y (the same as in the current image; modify the instructions given for your desired branch, of course).

Working logged in as your regular user, not root (for security), issue:

user@gentoo_pc ~ $ mkdir -pv kbuild && cd kbuild
user@gentoo_pc kbuild $ rm -rf linux
user@gentoo_pc kbuild $ git clone --depth 1 https://github.com/raspberrypi/linux.git -b rpi-5.4.y

This may take some time to complete, depending on the speed of your network connection.

When it has completed, go into the newly created linux directory, and set up the baseline bcm2711_defconfig:

user@gentoo_pc kbuild $  cd linux
user@gentoo_pc linux $  make ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- distclean
user@gentoo_pc linux $  make ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- bcm2711_defconfig

Next, modify the configuration if you like to suit your needs (this step is optional, as a kernel built with the stock bcm2711_defconfig will work perfectly well for most users):

user@gentoo_pc linux $  make ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- menuconfig

When ready, go ahead and build the kernel, modules, and dtbs. Issue:

user@gentoo_pc linux $  nice -n 19 make ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- -j$(nproc) Image modules dtbs

This does a parallel make, so on a modern PC, it shoudn't take long (5-15 mins). The build is forced to run at the lowest system priority, to prevent your machine becoming too unresponsive during this time.

With the kernel built, we need to install it. Insert the target microSD card into a reader on your PC (this card should already have the appropriate baseline bootfiles and system in place, as it will do if it has been created using the image provided in this project, for example). Let's assume your target microSD-card's boot directory is on /dev/mmcblk0p1, and its root is on /dev/mmcblk0p2 (adapt these paths to match your circumstances). Then, we begin by mounting these two partitions (I'm going to assume on /mnt/piboot and /mnt/piroot respectively; again, adapt as desired). Become root, and issue:

gentoo_pc ~ # mkdir -pv /mnt/pi{boot,root}
gentoo_pc ~ # mount -v /dev/mmcblk0p1 /mnt/piboot
gentoo_pc ~ # mount -v /dev/mmcblk0p2 /mnt/piroot

You can now can copy across the kernel (remember to back up the old version, if any, first, in case of problems). Substituting your regular user's account name (the one you logged into when building the kernel, above) for user in the below, issue:

gentoo_pc ~ # cd /home/user/kbuild/linux
gentoo_pc linux # cp -v arch/arm64/boot/Image /mnt/piboot/kernel8.img

Note that by default, the kernel does not require a separate U-Boot loader.

If you are also deploying kernels built from bcmrpi3_defconfig on the target, use a distinguished name for the bcm2711_defconfig kernel, such as /mnt/piboot/kernel8-p4.img, and then use the kernel=<...> directive in /mnt/piboot/config.txt, in a [pi4] fitered section, to select this kernel when the system is booted on an RPi4.

Next, copy over the device tree blob (at the time of writing there was only one):

gentoo_pc linux # cp -v arch/arm64/boot/dts/broadcom/TODO.dtb /mnt/piboot/

Then, copy over the device tree overlay blobs (there are now the responsibility of the binary kernel package, not the boot firmware any longer):

gentoo_pc linux # cp -rv arch/arm64/boot/dts/overlays /mnt/piboot/

If you also building a bcmrpi3_defconfig kernel from the same kernel source tree, it does not matter which of them supplies the overlays/ directory; the contents is identical in both cases.

Lastly, copy over the modules:

gentoo_pc linux # make ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- modules_install INSTALL_MOD_PATH="/mnt/piroot"
gentoo_pc linux # cd

and build metadata:

gentoo_pc linux # cp -v Module.symvers System.map /mnt/piboot/

Again, if you are also building a bcmrpi3_defconfig kernel from the same tree, call these files something distinct when you copy them; for example, Module-p4.symvers and System-p4.map. These files are for reference only (and help, for example, if building out-of-tree kernel modules at some later date), so they may safely be compressed (using xz or similar) if desired.

Note that we don't do a make firmware_install here, since that build target has been dropped for >= 4.14.

All done! You can now sync the filesystem, and unmount the microSD card partitions:

gentoo_pc ~ # sync
gentoo_pc ~ # umount -v /mnt/piboot
gentoo_pc ~ # umount -v /mnt/piroot
gentoo_pc ~ # rmdir /mnt/pi{boot,root}

Now you can remove the microSD card from your machine, insert it into your RPi4, and power on to try booting with your new 64-bit kernel!

Next Steps

Now that you have a functioning cross-compilation environment on your PC, why not hook it up to distcc? This will allow your RPi4 to leverage the power of your PC when performing local builds (for C and C++ compilation and header pre-processing), and makes it possible to use a source-based distribution like Gentoo without huge update times. See these instructions for details on how to proceed.

Clone this wiki locally