Crosscompiling modules for Raspberry 3
Compiling a module, and using it on Raspberry 3 without installing a new kernel can be a bit difficult, This description is based on the method described by Martin Kramer, and worked for us - it probably also works for Raspberry 2.
The computer used for the cross-compiling was running Debian (Jessie) and the Raspberry Pi 3 was running Raspbian kernel All commands are written in bold font - change the YourHomeDir to the name of your home directory.
Kernel compilation
First, the kernel has to be compiled. There is no need to actually use this newly compiled kernel, you can continue to use the kernel that is already installed in your Raspberry. The kernel will be compiled here to get information that is to be used when building modules. You only have to compile the kernel once, after that you can compile the modules any number of times. You will need the version control program git, no if not installed, install it (easiest with synaptic).
- Copy the cross-compiling tools from
github to the Debian-computer, and set
CCPREFIX to point to the correct tools:
~ $ git clone https://github.com/raspberrypi/tools
~ $ export CCPREFIX=/home/YourHomeDir/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
- Copy Raspbian source from github to
the same computer, and set KERNEL_SRC to
point to the source:
~ $ git clone https://github.com/raspberrypi/linux
~ $ export KERNEL_SRC=/home/YourHomeDir/linux
- On the Raspberry Pi, execute these
commands (ref: https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=57401,
comments by Zeta):
~ $ FIRMWARE_HASH=$(zgrep "* firmware as of" /usr/share/doc/raspberrypi-bootloader/changelog.Debian.gz | head -1 | awk '{ print $5 }')
~ $ echo $FIRMWARE_HASH
~ $ KERNEL_HASH=$(wget https://raw.github.com/raspberrypi/firmware/$FIRMWARE_HASH/extra/git_hash -O -)
~ $ echo $KERNEL_HASH
This should give a couple of hexadecimal git hashes, e.g. 03f35fe498e5516091e4fd66d1700e8d0b0f4915. The first hash indicates firmware version, the second one which version of the kernel is in use on the Raspberry Pi.
Still on the Raspberry, execute the commands:
~ $ su
~ $ modprobe configs
This installs a module that makes it possible to copy files from Rasbian to another computer, Secure Copy. This will be used later (from the Debian computer) to copy files from Raspbian.
- Back on the Debian-computer, select
the correct kernel version by giving
these commands:
~ $ cd linux
~/linux $ git checkout INSERT_KERNEL_HASH_HERE
This will choose the correct source branch (version) of the kernel.
- Now the cross compilation work can
begin: Execute
~/linux $ make mrproper
which cleans up the source directory: earlier generated files and configurations are deleted.
Copy a new kernel configuration file from the Raspberry Pi - this configuration file will control the compilation of the kernel:
~/linux $ scp pi@INSERT_THE_IP_NAME_OF_YOUR_RASPBERRY_HERE:/proc/config.gz ./
~/linux $ zcat config.gz > .config
The last command uncompresses the config file.
- Compile the kernel:
~/linux $ make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig
~/linux $ make ARCH=arm CROSS_COMPILE=${CCPREFIX}
These steps can take a long time (hours...).
If there were no errors, a new kernel image is available in /home/pernilla/YourHomeDir/linux/arch/arm/boot, but, as noted earlier, you do not need the kernel itself. To check that the correct kernel was compiled, execute the commands
~/linux $ cd ..
~ $ wget https://raw.githubusercontent.com/raspberrypi/firmware/INSERT_FIRMWARE_HASH_HERE/extra/Module7.symvers
This command fetches the original symbol table, Module7.symvers, from github. The firmware hash is the output from the 'echo $FIRMWARE_HASH' command that was executed on Raspbian earlier. If you are doing this for a Raspberry 1, substitute Module for Module7.
Compare the symbol table that was fetched from github with the one generated by the compilation - they should be identical:
~ $ diff -s Module7.symvers linux/Module.symvers
Files Module7.symvers.txt and linux/Module.symvers are identical
Now module compilation can begin.
Now module compilation can begin.
- Set variables to point at the source
and the tools, and execute make:
~/linux $ export SRC=/home/YourHomeDir/linux/drivers/spi
~/linux $ export PREFIX=/home/YourHomeDir/tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
~/linux $ make ARCH=arm CROSS_COMPILE=${PREFIX} -C /home/YourHomeDir/linux M=${SRC} modules
- Move compiled module(s) to the
Raspberry:
~/linux $ cd drivers/spi
~/linux $ /drivers/spi $ sftp pi@INSERT_THE_IP_NAME_OF_YOUR_RASPBERRY_HERE
ftp> put *.ko
Then, login to the Raspberry: move the original modules to safety and copy the new ones to the module directory
~ $ sudo mkdir /lib/modules/4.4.38-v7+/kernel/drivers/spi/Originals
~ $ sudo mv /lib/modules/4.4.38-v7+/kernel/drivers/spi/*.ko /lib/modules/4.4.38-v7+/kernel/drivers/spi/Originals
~ $ sudo cp *.ko /lib/modules/4.4.38-v7+/kernel/drivers/spi
~ $ sudo rmmod spi_bcm2835
~ $ sudo modprobe spi_bcm2835
The new version of the module is now loaded into the kernel and can be tested (check with lsmod command).
If you notice errors, please let us know info [at] tietonoita [dot] fi