Rebuilding the Kernel

These instructions aim to help you rebuild the kernel for the development board separately from the process of building a new image in its entirety. It also covers the process of installing the kernel and other binaries on the board. The building step can be performed without any modifications to the board.

Preparations

While it is possible to replace an existing kernel with a new one, you may find it useful to attach a USB to serial adapter to the board so that can interact with the bootloader and select a different kernel to run. This makes it possible to install new kernels alongside the original one and fall back to the original one if the new ones fail to work.

Installing the Toolchain

Install the necessary packages for your system. On Debian-based systems, you can do this with the apt tool:

sudo apt install crossbuild-essential-arm64 build-essential gcc-aarch64-linux-gnu bison flex libssl-dev bc kmod

On Fedora, use the dnf tool to install the extra packages. For example:

sudo dnf install gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu

It should now be possible to cross-compile the kernel for the development board.

Building the Kernel

Clone the linux-emcraft repository and enter the working directory:

git clone -b imx8-5.2-devkit https://source.puri.sm/Librem5/linux-next.git linux-next-5.2
cd linux-next-5.2

For simplicity, we create a directory to hold the modules that will be built:

mkdir _modules

Compile the kernel, optionally using ccache if installed:

# With ccache:
CROSS_COMPILE='ccache aarch64-linux-gnu-' \
INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=_modules \
make ARCH=arm64 librem5-devkit_defconfig all modules_install

# Without ccache:
CROSS_COMPILE=aarch64-linux-gnu- \
INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=_modules \
make ARCH=arm64 librem5-devkit_defconfig all modules_install

You can also pass the -j command line option to make if you want to compile many files in parallel, specifying the number of parallel builds as an argument to the option.

Installing the Kernel

Connect the development board to a network and find its IP address. Log in as root and create the boot2 directory and dtbs subdirectory inside the existing /boot directory:

mkdir -p /boot/boot2/dtbs

From the workstation, copy the kernel and device tree binary to the board, replacing pureos with the IP address of the development board:

scp arch/arm64/boot/Image root@pureos:/boot/boot2/
scp arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dtb  root@pureos:/boot/boot2/dtbs/

Remove the source and build symlinks from the modules directory and copy the directory for the corresponding kernel version to the correct location on the board, replacing $KERNEL_VERSION with the version of the kernel that was built:

rm _modules/lib/modules/$KERNEL_VERSION/source
rm _modules/lib/modules/$KERNEL_VERSION/build
scp -r _modules/lib/modules/$KERNEL_VERSION root@pureos:/lib/modules/

The board should now be ready to reboot into the new kernel.

Booting into U-Boot

Plug in the USB to serial adapter and open a serial connection, replacing ttyUSB0 with the appropriate device file if necessary:

picocom -b 115200 /dev/ttyUSB0

Reboot the development board and wait until you see the following text:

Hit any key to stop autoboot:

Press Return and enter the following commands at the U-Boot prompt:

setenv bootdir boot2/
boot

The new kernel should be loaded and run.

To boot into the old kernel, reboot and let it autoboot. This should work as long as the old kernel image, device tree binary and modules are still installed.

If you need to restore the system to use a working kernel and bootloader, follow the instructions in Flashing the System Image.