Notes on how to set up a new Ubuntu 18.04 LTS x64 environment, how to build the Mainline Kernel and place it on a Raspbian SD card.

Procedure

Install tools needed:

# apt install git make gcc device-tree-compiler bison flex libssl-dev libncurses-dev
  1. Install an up-to-date cross compiler and associated toolset. This may be obtained fromhttps://releases.linaro.org/components/toolchain/binaries/latest-7/​. The directoryarm-linux-gnueabihf​ contains the necessary compiler for ARM 32-bit and the directoryaarch64-linux-gnu for ARM 64-bit.

Choose the version suited to your development machine's architecture. For example, at the present time, for use on 64-bit Ubuntu 18.04 on an Intel-based development machine, the appropriate version is gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz.

$ wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz
$ sudo tar xf gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz -C /opt
  1. Get Raspberry Pi Linux Sources
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
  1. Move into the repository folder and setup cross-compiler (for ARM 64-bit replaceARCH=arm​ withARCH=arm64):
$ cd linux
$ export ARCH=arm
$ export CROSS_COMPILE=/opt/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
  1. Choose the kernel configuration. To do this, you need to know what model of System on a Chip (SoC) is used on your Pi. Please refer to theRaspberry Pi Wikipedia Section​. Since we are building from an upstream source, then, by reference toEric Anholt's pages​ we can deduce that we should selectbcm2835_defconfig​ for BCM2835-based models,multi_v7_defconfig​ for BCM2836-, BCM2837- and BCM2711-based models (ARM 32-bit) ordefconfig for BCM2837- and BCM2711-based models (ARM64). For the Raspberry Pi 3B Plus (ARM 32-bit), the following is appropriate:
$ make multi_v7_defconfig
  1. At this point you can modify the configuration using, for instance,menuconfig:
$ make menuconfig
  1. Build the kernel, the modules and the device tree blobs:
$ make

To speed up compilation on a multicore machine, add the argument -j <number_of_cores+1> to the above command.

  1. Insert an existing Raspbian SD Card to your development machine. In Ubuntu 18.04, it will appear at/media/<username>/boot​ and/media/<username>/rootfs​, where<username> is the username you are logged in under.
  2. Identify the appropriate kernel file to replace. For some models, the operative kernel is in/media/<username>/boot/kernel.img​, whereas in others including the Raspberry Pi 3B Plus used here, it is in the file/media/<username>/boot/kernel7.img​. Refer to theofficial Kernel Building documentation​ to identify the correct kernel file. Copy the kernel file to the card's boot directory, renaming the existing kernel file beforehand to preserve it (for ARM 64-bit the kernel file is justImage):
$ cp arch/arm/boot/zImage /media/<username>/boot/
  1. Copy the device tree blob to the card's boot directory. The exact device tree blob file to use depends on the model. The following is for a Raspberry Pi 3B Plus, so the device tree blob's filename isbcm2837-rpi-3-b-plus.dtb:
$ cp arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dtb /media/<username>/boot/
  1. Adjust the device tree information in/media/<username>/boot/config.txt:
  • Add the following lines to/media/<username>/boot/config.txt​. The filename is that of the device tree blob copied over in Step 10. If/media/<username>/boot/config.txt​ already contains adevice_tree entry, replace it with this.
device_tree=bcm2837-rpi-3-b-plus.dtb
kernel=zImage
  1. Copy the kernel modules to the SD card. Note that you need to be in superuser mode for this (for ARM 64-bit replaceARCH=arm​ withARCH=arm64):
# sudo ARCH=arm make modules_install INSTALL_MOD_PATH=/media/<username>/rootfs
  1. Safely dismount the SD card from the development machine, put it into the target machine and reboot.

Notes

  • Avoid usingrpi-update, as it will overwrite your mainline binary. The downstream kernel typically has problems with the upstream device tree blob.
  • In some cases (e.g. thearm64), the kernel image tends to be very big (~ 16 MB) and may hit the limit of the boot partition.