Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save vondraussen/bbf737710808aaef2d505549b8080040 to your computer and use it in GitHub Desktop.
Save vondraussen/bbf737710808aaef2d505549b8080040 to your computer and use it in GitHub Desktop.
Add a Cross Compiled Kernel Module (Raspberry Pi)

Add a Cross Compiled Kernel Module (Raspberry Pi)

I made the following notes while I was compiling a Kernel module (SI7020 Humidity/Temp Sensor) for the Raspberry Pi. The module was not part of the precompiled modules shipped with Raspbian. The steps should be the same if you want to build a different module.

I didn't want to install the Kernel headers or build modules on the Raspberry Pi.

Keep in mind, that a new module has to be build and installed once you update the Kernel!

Get Installed Kernel Version

Get the Kernel Version Tag

apt search raspberrypi-kernel
# raspberrypi-kernel/stable,now 1.20190819~stretch-1 armhf [installed]

The git tag is the info we are looking for. In this example it is 1.20190819. It's not the full tag though. If you browse the github repo for that tag you'll find the following: https://github.com/raspberrypi/linux/tree/raspberrypi-kernel_1.20190819-1

That is the commit we need to clone or checkout if you have the full history repo.

The Kernel version/tag will not match, if you did run a rpi-update before. You should go back to the default Kernel, if you can.

sudo apt update
sudo apt install --reinstall raspberrypi-bootloader raspberrypi-kernel

So we will clone as follows

git clone --depth 1 --branch raspberrypi-kernel_1.20190819-1 https://github.com/raspberrypi/linux.git

Cross Compile Kernel Module

RasperryPi Docu

  1. git clone --depth 1 https://github.com/raspberrypi/tools
  2. create a script to setup the toolchain when needed:
# setup_toolchain.sh
#!/bin/bash
export PATH=$PATH:$PWD/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
  1. source it source ./setup_toolchain.sh
  2. install needed tools to your build machine
# ubuntu
sudo apt install bison flex libssl-dev
# fedora
sudo dnf install bison flex openssl-devel
  1. Follow the official guide to setup make for the Kernel you need for your Hardware. For example building for a Pi 3B+:
cd linux
KERNEL=kernel7 make -j $(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
  1. Now It's time to make your changes by using the command below. The only thing I added was the driver for the SI7020 I2C humidity temperature sensor.
KERNEL=kernel7 make -j $(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
  1. Make the modules
make -j $(nproc) ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules
  1. The module will be in: drivers/iio/humidity/si7020.ko
  2. Copy the module to your PI
scp drivers/iio/humidity/si7020.ko pi@pi-usa:/tmp/
ssh pi-usa
# now on the pi do:
sudo cp /tmp/si7020.ko /lib/modules/4.19.66-v7+/kernel/drivers/iio/humidity/
  1. You can check the module info against an already installed one
modinfo /lib/modules/4.19.66-v7+/kernel/drivers/iio/humidity/si7020.ko
# the vermagic should be the same, for me it is
# vermagic: 4.19.66-v7+ SMP mod_unload modversions ARMv7 p2v8
  1. Register the module sudo depmod
  2. Load the module modprobe si7020
  3. Check that the module was loaded lsmod | grep si7020
  4. To auto load the module, add the name to /etc/modules

Autoload I2C Driver

Create a systemd service unit in /etc/systemd/system/si7020.service

# /etc/systemd/system/si7020.service
[Unit]
Description=load si7020 i2c driver

[Service]
Type=oneshot
ExecStart=/bin/echo si7020 0x40 > /sys/bus/i2c/devices/i2c-1/new_device

[Install]
WantedBy=multi-user.target

To enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable si7020
sudo systemctl start si7020

Read SI7020 Values from the IIO sysfs interface

Temperature

cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_raw
# 6052
cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_offset
# -4368
cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_scale
# 10.725097656

# calc the result
# (raw + offset) * scale
# we can use bc to calc that for us (example in Degree C)
echo "((6053-4368)*10.7251)/1000" | bc -l
# 18.07179350000000000000

# or as a one liner (could be saved as a script)
TEMP=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_raw) && \
OFF=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_offset) && \
SCALE=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_temp_scale) && \
echo "(($TEMP + $OFF)*$SCALE)/1000" | bc -l

Humidity

See temperature for details.

HUMI=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_humidityrelative_raw) && \
OFF=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_humidityrelative_offset) && \
SCALE=$(cat /sys/module/si7020/drivers/i2c\:si7020/1-0040/iio\:device0/in_humidityrelative_scale) && \
echo "(($HUMI + $OFF)*$SCALE)/1000" | bc -l
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment