-
Notifications
You must be signed in to change notification settings - Fork 126
Build an RPi4 64bit Kernel on your crossdev PC
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.
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.
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 thebcm2711_defconfig
kernel, such as/mnt/piboot/kernel8-p4.img
, and then use thekernel=<...>
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 theoverlays/
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
andSystem-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 (usingxz
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!
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.
Wiki content license: Creative Commons Attribution-ShareAlike 4.0 International License