Installing the RPi5 kernel from your Mac
Using a new Docker image which supports build and install.
G’day folks, I’m back again with an updated tip on building and installing a custom kernel image on your RPi5 board.
In order to fully understand and follow this article, please read my previous article detailing how to build an RPi5 kernel using Docker - especially important is to note the need for case-sensitive filesystems when building on MacOS.
This article gives a second simple option via Docker to build and additionally install the kernel on your RPi5 board from your Mac with minimal fuss.
I’m quite sure the following steps will work on Windows or Linux thanks to the magic of Docker. If you try this out feel free to comment on your experience below, I’m happy to help if issues are encountered.
Docker image redux
Although the docker image mentioned in the previous article is great, the documentation with regards to installing the kernel onto the RPi5 is lacking.
I decided to modify the Docker image to make things a bit easier on the end user (me!). After some googling, I came across this page, which provides a couple of scripts which automate both the building and installing of the RPi kernel.
Steps to check out the Docker image I’ve created:
Step 1: clone the Docker configuration from github1. Note: please make sure this is done inside a case-sensitive filesystem. For details on case-sensitive filesystems please read my previous RPi5 kernel article:
wifi@mbp pi-kernel % git clone git@github.com:rkinder2023/pi-kernel.git
Step 2: Run the builder command, which will drop you into a shell from where you can build and install the kernel.
wifi@mbp pi-kernel % ./builder
Building the kernel
Step 1: Run the build-kernel script and answer the questions - my example responses are given in bold, your responses may differ:
root@1a9bc30160cb:/build# ./build-kernel
Cross-compile mode (y/n)? y
1) Raspberry Pi 1, Zero and Zero W, and Raspberry Pi Compute Module 1 (32-bit) [kernel.img]
2) Raspberry Pi 2, 3, 3+ and Zero 2 W, and Raspberry Pi Compute Modules 3 and 3+ (32-bit) [kernel7.img]
3) Raspberry Pi 4 and 400, and Raspberry Pi Compute Module 4 (32-bit) [kernel7l.img]
4) Raspberry Pi 3, 3+, 4, 400 and Zero 2 W, and Raspberry Pi Compute Modules 3, 3+ and 4 (64-bit) [kernel8.img]
5) Raspberry Pi 5 (64-bit) [kernel_2712.img]
Configuration: 5
Ok to install wget (y/n)? y
Hit:1 http://deb.debian.org/debian buster InRelease
Hit:2 http://deb.debian.org/debian-security buster/updates InRelease
Hit:3 http://deb.debian.org/debian buster-updates InRelease
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
wget
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 888 kB of archives.
After this operation, 3327 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian buster/main arm64 wget arm64 1.20.1-1.1 [888 kB]
Fetched 888 kB in 0s (8339 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package wget.
(Reading database ... 23405 files and directories currently installed.)
Preparing to unpack .../wget_1.20.1-1.1_arm64.deb ...
Unpacking wget (1.20.1-1.1) ...
Setting up wget (1.20.1-1.1) ...
Branch (commitid/current/default/rpi-M.N.y): rpi-6.6.y
Suffix (blank = none): wifidiving
Use old boot mount (/boot) (y/n)? n
Number of jobs (blank = 4): 8
Run menuconfig (y/n)? n
Interactive shell before compile (y/n)? n
Purge source files upon completion (y/n)? n
Configuration: Raspberry Pi 5 (64-bit) [kernel_2712.img]
Cross-compile mode: yes
Branch: rpi-6.6.y
Suffix: wifidiving
Use old boot mount (/boot): no
Disable running update-initramfs: no
Jobs: 8
Run menuconfig: no
Interactive shell: no
Purge source files upon completion: no
Build kernel (y/n)? y
Downloading source files (this may take a while)
Step 2: Wait until the kernel downloads and the build completes, after which a message like this should appear:
...
XZ /tmp/build-kernel-dstdir-4fqOw/lib/modules/6.6.29-rpi999-rpi-2712/kernel/net/vmw_vsock/vsock_loopback.ko.xz
INSTALL /tmp/build-kernel-dstdir-4fqOw/lib/modules/6.6.29-rpi999-rpi-2712/kernel/net/nsh/nsh.ko
XZ /tmp/build-kernel-dstdir-4fqOw/lib/modules/6.6.29-rpi999-rpi-2712/kernel/net/nsh/nsh.ko.xz
DEPMOD /tmp/build-kernel-dstdir-4fqOw/lib/modules/6.6.29-rpi999-rpi-2712
Kernel successfully built
root@1a9bc30160cb:/build#
The built kernel + modules will be in the ‘/root’ home directory within the Docker container shell:
root@1a9bc30160cb:/build# ls ~
kernel-6.6.29-v8-16k-wifidiving.zip
Installing the kernel
Step 1: boot up your RPi device, make sure it’s connected to the same network as your Mac device. In my case, the RPi is at 192.168.1.42.
Step 2: enable ssh on your device by clicking the Raspberry in the top left → Preferences → Raspberry Pi Configuration → Interfaces (tab) and toggle the ‘SSH’ selector.
Step 3: Allow root SSH access. Do this by editing the file ‘/etc/ssh/sshd_config’ on your RPi device:
wifid@raspberrypi:~ $ sudo vi /etc/ssh/sshd_config
Modify the line:
#PermitRootLogin prohibit-password
to:
PermitRootLogin yes
Step 4: Add a root password:
wifid@raspberrypi:~ $ sudo su -
root@raspberrypi:~# passwd
New password:
Step 5: Make a directory as a mount point for your root RPi filesystem:
root@1a9bc30160cb:/build# mkdir rpiroot
Step 6: Mount your RPi via sshfs into your Docker container filesystem. Note: as previously mentioned, my RPi is at 192.168.1.42:
root@1a9bc30160cb:/build# sshfs root@192.168.1.42:/ ./rpiroot
Step 7: Copy across the built kernel tree/modules/… and the install-kernel script:
root@1a9bc30160cb:/build# cp ~/kernel-6.6.29-v8-16k-wifidiving.zip ./rpiroot/
root@1a9bc30160cb:/build# cp install-kernel ./rpiroot/
Step 8: On the RPi board, as the root user, run the ‘install-kernel’ script:
root@raspberrypi:~# ls
install-kernel kernel-6.6.29-v8-16k-wifidiving.zip
root@raspberrypi:~# ./install-kernel ./kernel-6.6.29-v8-16k-wifidiving.zip
Ok to install ./kernel-6.6.29-v8-16k-wifidiving.zip (y/n)? y
...
Building cpio /boot/initrd.img-6.6.29-rpi999-rpi-2712.new initramfs
'/boot/initrd.img-6.6.29-rpi999-rpi-2712' -> '/boot/firmware/initramfs_2712'
Kernel installation completed
Reboot required to use new kernel
Reboot now (y/n)? y
After reboot your board should be running the new kernel - the one you built!
Developing the kernel
With the default Docker image installed from GitHub, the source code for the Linux kernel will be inside the ‘.src’ subdirectory of your pi-kernel git checkout, as a host mounted filesystem. Any changes you make inside this subdirectory will persist across container restarts until you remove the subdirectory.
wifi@mbp pi-kernel % ls -al
total 96
drwxr-xr-x 11 wifi staff 352 30 Apr 15:01 .
drwxr-xr-x 4 wifi staff 128 30 Apr 12:34 ..
drwxr-xr-x 5 wifi staff 160 30 Apr 14:34 .build
drwxr-xr-x 13 wifi staff 416 30 Apr 15:01 .git
-rw-r--r-- 1 wifi staff 21 30 Apr 12:34 .gitignore
drwxr-xr-x 3 wifi staff 96 30 Apr 14:48 .src
-rw-r--r-- 1 wifi staff 367 30 Apr 14:32 Dockerfile
-rw-r--r-- 1 wifi staff 1893 30 Apr 15:01 README.md
-rwxr-xr-x@ 1 wifi staff 25246 30 Apr 12:35 build-kernel
-rwxr-xr-x 1 wifi staff 746 30 Apr 14:37 builder
-rwxr-xr-x 1 wifi staff 2420 30 Apr 12:35 install-kernel
wifi@mbp pi-kernel %
That’s all for now - hope this hint helped.
Please let me know how you go with this new method, especially if you get it running on a Windows host machine.