To make your custom kernel work with Navio2 for running Ardupilot, some overlays and a kernel module must be included. This article is a note of what I did to create my own kernel that’s workable with Navio2 for Ardupilot.
- You are to cross-compile the custom kernel on a Ubuntu desktop (I personally run my Ubuntu in a VM) and flash it onto a SD card for booting on a Raspberry Pi 3/4 board.
- You have ARM Cross-Compiler Tool Chain and Build Dependencies installed properly with
~/tools/as the tool’s root directory.
You can get the compiler as instructed here or using the commands below:
git clone https://github.com/raspberrypi/tools ~/tools sudo apt update sudo apt install git bison flex libssl-dev
- You have a working SD card that is flashed with the Raspbian’s image that matches your kernel version.
[Step 0] Preparation
First, you should get your kernel’s working directory ready.
As an example here, I’m cloning a branch from my GitHub repository:
cd ~ git clone --depth=1 https://github.com/cchen140/linux-rt-rpi.git cd linux-rt-rpi git checkout -b rpi-4.19.y-rt origin/rpi-4.19.y-rt # check out the desired remote branch git checkout -b rpi-4.19.y-rt-navio2 # switch to a new branch name git push -u origin rpi-4.19.y-rt-navio2 # push the new branch to remote
Make sure you have checked out the branch you’d like to work on. Then, we must patch our custom kernel to include Navio 2’s code.
I have created a patch
To download and apply the patch, go to the root directory of your kernel code and run:
wget https://gist.github.com/cchen140/07159b29a21be929b545ad6c268ef3cc/raw/navio2-4.19.83.patch git apply --stat navio2-4.19.83.patch git apply --check navio2-4.19.83.patch git am -3 < navio2-4.19.83.patchYou should resolve any patching error before you move on.
cd ~ git clone --depth=1 https://github.com/cchen140/linux-rt-rpi.git cd linux-rt-rpi git checkout rpi-4.19.83-navio git format-patch -8 HEAD --stdout > navio2-4.19.83.patch
[Step 2] Patch for RCIO Kernel Module
Navio 2 also depends on the RCIO kernel module which is maintained in a separate repository (source and forked).
As a result, applying the patch we made in last step is insufficient to make our kernel work with Navio2. There are two ways to tackle this problem (we will take the 1st approach):
- Integrate the RCIO kernel module source code into our kernel code base.
- Without the integration, we’ll have to compile and install the module separately (see this post for detailed steps if you’d like to take this approach).
To integrate the RCIO kernel module into your kernel, use the patch (coming from a commit I made) as follows:
wget -O rcio.patch https://github.com/cchen140/linux-rt-rpi/commit/253861034e6ad170ccb4c84129c56d7945a613af.patch git apply --stat rcio.patch git apply --check rcio.patch git am < rcio.patchAgain, you should resolve any patching error before you move on.
[Step 3] Cross-Compile
At this point, all the changes for Navio2 have been integrated into your kernel.
To configure your kernel, you will need to use
After that, use the following commands to compile your kernel (and please remember to check your tool’s path — here I’m assuming it is located under
echo PATH=\$PATH:~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin >> ~/.bashrc source ~/.bashrc KERNEL=kernel7 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_navio2_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j 2
echo PATH=\$PATH:~/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin >> ~/.bashrc source ~/.bashrc KERNEL=kernel7l make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_navio2_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j 2
[Step 4] Update Raspberry Pi SD Card
Before you proceed, let’s create two folders for mounting the SD card’s two partitions (creating folders only has to be done once).
mkdir mnt mkdir mnt/fat32 mkdir mnt/ext4
Then, insert your SD card and run the following commands to flash your new kernel onto your SD card (assuming your you have your SD card on sdb1 and sdb2):
sudo mount /dev/sdb1 mnt/fat32 sudo mount /dev/sdb2 mnt/ext4 sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img sudo cp arch/arm/boot/zImage mnt/fat32/$KERNEL.img sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/ sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/ sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/ sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install sudo umount mnt/fat32 sudo umount mnt/ext4
After all these steps, you should be able to put your SD card back to your Raspberry Pi board and boot up.
[Step 5] Revise Boot Configurations for Device Tree Overlays
To allow a correct communication between Raspberry Pi and Navio2, add the DT overlay configurations at the end of the boot configuration file
dtparam=spi=on dtoverlay=spi0-4cs dtoverlay=spi1-1cs,cs0_pin=16,cs0_spidev=disabled dtoverlay=rcio dtoverlay=navio-rgb dtparam=i2c1=on dtparam=i2c1_baudrate=1000000
[Step 6] Load RCIO Kernel Module
At this point when Linux is booted up, the RCIO kernel module is loaded yet.
To manually load the RCIO module, use the following commands:
sudo modprobe rcio_spi sudo modprobe rcio_core
To verify if the RCIO kernel module has been correctly loaded, you can use
dmesg. An example is given as follows:
lsmod | grep rcio
You should see a similar output like shown below if RCIO is running correctly.
rcio_spi 16384 0 rcio_core 36864 1 rcio_spi
To make Linux load the RCIO module automatically on boot, add the module names in the file
[Step 7] Install Ardupilot
Please refer to this post for detailed steps for installing and running Ardupilot.
I conclude the commands here:
# To get source code git clone https://github.com/ArduPilot/ardupilot cd ardupilot git checkout Copter-3.6.11 git submodule update --init --recursive # To compile alias waf="$PWD/modules/waf/waf-light" waf configure --board=navio2 waf copter # To launch sudo build/navio2/bin/arducopter -A udp:192.168.1.9:14550