CSE 422S: Compiling On-Board your Raspberry Pi


Cross compilation is advantageous in many cases, especially on a multi-core server with significantly more processing power than your Raspberry Pi. However, in some cases such resources may not be available and in any case it's worth understanding how to build kernels and other software directly on-board a Raspberry Pi computer itself.

Note that these instructions assume you will be able to ssh into your Raspberry Pi from another computer, which should work in a straigtforward manner over a dedicated wired connection, but for wireless networks (due to differing network security configurations) may require additional certificates or other workarounds in order to be successful. Your mileage may vary.

To get started, first ensure that your Raspberry Pi computer is configured to enable ssh access. Do this by clicking on the raspberry icon in the top left corner of your Pi, selecting Preferences, and then Raspberry Pi Configuration. Then, select the Interfaces tab, and enable SSH.

Now, ssh into your Raspberry Pi computer using its IP address (which you can obtain by issuing the ifconfig or hostname -I command in a terminal window on your Raspberry Pi.

If you encounter problems with your Raspberry Pi freezing up during any of the steps below, you may want to reboot it, obtain its IP address, and then unplug the HDMI, mouse, and keyboard cables from your Raspberry Pi (to avoid problems involving their device drivers) before accessing the running Raspberry Pi (solely) through SSH.

Please note that the instructions that follow also can be performed directly within a terminal window on the Raspberry Pi itself, though we assume SSH is used to avoid problems with the Raspberry Pi itself freezing up during compiles and other long-running operations.

Instructions for On-Board Kernel Compilation

  1. As you did in the first studio, make a new directory called linux_source to organize your source code, move into that directory, and then issue the following commands, each of which will take several minutes:

    wget https://github.com/raspberrypi/linux/archive/raspberrypi-kernel_1.20200527-1.tar.gz

    tar -xzf raspberrypi-kernel_1.20200527-1.tar.gz

    Once the files finish unzipping you'll have a new directory, which you should again rename to be something simpler like linux. Navigate to this directory

  2. Now we'll verify that our system has all of the required prerequisites for building the kernel, by issuing the commands:

    sudo apt-get update

    sudo apt-get install bc ncurses-dev flex bison libssl-dev

  3. To configure the Linux kernel (starting from reasonable default settings for the Raspberry Pi), issue the commands:

    make bcm2709_defconfig

    Next, we want to set a custom configuration option. Issue the command:

    make menuconfig

    First, you'll add your own unique identifier to the kernel you build. Navigate to "General setup", then select "Local version." The local version string you specify here will be appended to the output of the uname command. If you applied the default Raspberry Pi configuration correctly, this currently should be set to "-v7". Go ahead and append your own unique identifier to that string, though recall that uname already gives you the kernel version number, the day and time the kernel was compiled, as well as other info. Warning: do not include any spaces in the local version string - this will break the build script when you run sudo make modules_install in the future.

    Next, we will change the kernel's preemption model. While still in "General setup," select "Preemption Model," and then select the "Preemptible Kernel (Low-Latency Desktop)" option. Then exit "General setup" to return to the main configuration menu.

    After a moment, you'll get a kernel configuration menu. First, we will make the kernel more preemptable. Go into "Kernel Features", then select "Preemption Model", and then select "Preemptible Kernel (Low-Latency Desktop)".

    Next you'll add your own unique identifier to the kernel you build. Navigate to "Local version" under "General setup". The local version string you specify here will be appended to the output of the uname command. If you applied the default Raspberry Pi configuration correctly, this should be set to "-v7". Go ahead and add your own unique identifier, though recall that uname already gives you the kernel version number, the day and time the kernel was compiled, as well as other info.Warning: do not include a space in the local version string- this will break the build script when you run sudo make modules_install.

    Once you're done, exit the configurator and be sure to answer "Yes" when asked to save your changes.

  4. Finally, we're able to start compiling the kernel, which will take about an hour and a half. To begin, issue the command:

    make -j8 zImage modules dtbs

    make -j4 zImage modules dtbs

    Once it's done, issue the following commands:

    sudo make modules_install

    sudo cp arch/arm/boot/dts/*.dtb /boot/

    sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/

    sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/

    sudo cp arch/arm/boot/zImage /boot/kernel7.img

    sudo scripts/mkknlimg arch/arm/boot/zImage /boot/$KERNEL.img

    At this point, your new kernel is installed. When you reboot, you'll be running your very own, custom kernel.

    Go ahead and reboot now. If everything went OK, the new system should look and feel the same as before. You can verify that your new kernel is running with the command uname -a. In particular, the build date should be today, the version string should include the local version string you specifed during configuration, and your linux source code version with the characters "PREEMPT" should appear.