How to cross-compile kernel module?
Hi everyone,
I'm trying to build and cross-compile loadable kernel modules for the Raspberry Pi 5.
My setup:
Downloaded manually and flashed using Raspberry Pi Imager ("Use custom")
Image used: https://downloads.raspberrypi.com/raspi ... 025-11-24/
Source checkout:
To match the kernel version used in the image, I cloned the Raspberry Pi Linux repo:
https://github.com/raspberrypi/linux.git
Based on the release notes here:
https://downloads.raspberrypi.com/raspi ... _notes.txt
I checked out commit:
359f37f0faefb712add32a39f98751aea67d5c1f
Cross-compiling:
I followed the Raspberry Pi documentation:
https://www.raspberrypi.com/documentati ... the-kernel
Commands used:
sudo apt install bc bison flex libssl-dev make libc6-dev libncurses5-dev
sudo apt install crossbuild-essential-arm64
cd linux
KERNEL=kernel_2712
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION="" bcm2712_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION="" Image modules dtbs
After building, I copied the .ko and .dtbo files to the Raspberry Pi via SCP.
When enabling the device tree overlay and loading the modules, dmesg reported symbol version mismatches.
My question:
Am I on the wrong kernel commit, or am I missing something in the build process?
Additional details:
I believe I'm using the latest stable firmware, since I flashed the latest official image.
The firmware repo lists the kernel commit here:
https://github.com/raspberrypi/firmware ... a/git_hash
I also found information that official Raspberry Pi OS kernels contain two sets of patches:
Debian patches and Raspberry Pi–specific patches (from raspberrypi/linux)
This suggests that the upstream repo: https://github.com/raspberrypi/linux.git does not exactly match the kernel shipped in the official image.
Reference:
viewtopic.php?p=2210334#p2210334
What I'm trying to achieve:
I want to cross-compile kernel modules without modifying the kernel image on the Raspberry Pi.
I'm only adding a new loadable module under media/i2c, not altering the kernel itself.
Previously, I successfully built modules using the image:
https://downloads.raspberrypi.com/raspi ... 024-11-19/
using the same workflow.
If anyone can clarify the correct process — especially regarding the proper kernel source and patches needed to match the official Raspberry Pi OS kernel — I would really appreciate the help.
Thanks!
I'm trying to build and cross-compile loadable kernel modules for the Raspberry Pi 5.
My setup:
- Device: Raspberry Pi 5
- System: Raspberry Pi OS (64-bit)
- Kernel version: 6.12.47
- Debian version: 13 (trixie)
Downloaded manually and flashed using Raspberry Pi Imager ("Use custom")
Image used: https://downloads.raspberrypi.com/raspi ... 025-11-24/
Source checkout:
To match the kernel version used in the image, I cloned the Raspberry Pi Linux repo:
https://github.com/raspberrypi/linux.git
Based on the release notes here:
https://downloads.raspberrypi.com/raspi ... _notes.txt
I checked out commit:
359f37f0faefb712add32a39f98751aea67d5c1f
Cross-compiling:
I followed the Raspberry Pi documentation:
https://www.raspberrypi.com/documentati ... the-kernel
Commands used:
sudo apt install bc bison flex libssl-dev make libc6-dev libncurses5-dev
sudo apt install crossbuild-essential-arm64
cd linux
KERNEL=kernel_2712
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION="" bcm2712_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- LOCALVERSION="" Image modules dtbs
After building, I copied the .ko and .dtbo files to the Raspberry Pi via SCP.
When enabling the device tree overlay and loading the modules, dmesg reported symbol version mismatches.
My question:
Am I on the wrong kernel commit, or am I missing something in the build process?
Additional details:
I believe I'm using the latest stable firmware, since I flashed the latest official image.
The firmware repo lists the kernel commit here:
https://github.com/raspberrypi/firmware ... a/git_hash
I also found information that official Raspberry Pi OS kernels contain two sets of patches:
Debian patches and Raspberry Pi–specific patches (from raspberrypi/linux)
This suggests that the upstream repo: https://github.com/raspberrypi/linux.git does not exactly match the kernel shipped in the official image.
Reference:
viewtopic.php?p=2210334#p2210334
What I'm trying to achieve:
I want to cross-compile kernel modules without modifying the kernel image on the Raspberry Pi.
I'm only adding a new loadable module under media/i2c, not altering the kernel itself.
Previously, I successfully built modules using the image:
https://downloads.raspberrypi.com/raspi ... 024-11-19/
using the same workflow.
If anyone can clarify the correct process — especially regarding the proper kernel source and patches needed to match the official Raspberry Pi OS kernel — I would really appreciate the help.
Thanks!
- 6by9
- Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator - Posts: 18540
- Joined: Wed Dec 04, 2013 11:27 am
Re: How to cross-compile kernel module?
What happened to copying the kernel image file?
To install the 64-bit kernel:
Run the following commands to create a backup image of the current kernel, install the fresh kernel image, overlays, README, and unmount the partitions:Code: Select all
sudo cp mnt/boot/$KERNEL.img mnt/boot/$KERNEL-backup.img sudo cp arch/arm64/boot/Image mnt/boot/$KERNEL.img <<<<<<<<<<<<<<<<<<<<<<<<<<<< sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/boot/ sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/boot/overlays/ sudo cp arch/arm64/boot/dts/overlays/README mnt/boot/overlays/ sudo umount mnt/boot sudo umount mnt/root
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: How to cross-compile kernel module?
I didn’t copy the kernel Image because I’m not modifying anything that gets built into the kernel itself. I’m only adding out-of-tree loadable modules.
With NVIDIA Jetson development, this is normally how it works too: as long as you don’t touch code that’s actually built into the kernel image, you can compile just the modules and load them without replacing the running kernel.
That’s why I’m asking — why would copying the kernel Image be required here?
If I overwrite the kernel Image on the Raspberry Pi, wouldn’t I actually lose the Debian patches that the official Raspberry Pi OS kernel includes? Those patches aren’t present in the raspberrypi/linux repo, so replacing the Image with my own would give me a kernel that doesn’t match the rest of the system.
Since my module is loadable and not part of the built-in kernel, I would expect it to work as long as I’m compiling against the exact same kernel sources and configuration.
So if copying the kernel Image is really necessary, could someone explain why that is needed in this case?
Why doesn’t an out-of-tree module compile cleanly against the kernel in the official image?
With NVIDIA Jetson development, this is normally how it works too: as long as you don’t touch code that’s actually built into the kernel image, you can compile just the modules and load them without replacing the running kernel.
That’s why I’m asking — why would copying the kernel Image be required here?
If I overwrite the kernel Image on the Raspberry Pi, wouldn’t I actually lose the Debian patches that the official Raspberry Pi OS kernel includes? Those patches aren’t present in the raspberrypi/linux repo, so replacing the Image with my own would give me a kernel that doesn’t match the rest of the system.
Since my module is loadable and not part of the built-in kernel, I would expect it to work as long as I’m compiling against the exact same kernel sources and configuration.
So if copying the kernel Image is really necessary, could someone explain why that is needed in this case?
Why doesn’t an out-of-tree module compile cleanly against the kernel in the official image?
- 6by9
- Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator - Posts: 18540
- Joined: Wed Dec 04, 2013 11:27 am
Re: How to cross-compile kernel module?
In which case you need to copy the config file from the running kernel rather than running "make XXX_defconfig", and set your .version file appropriately.
The kernel you're running will report something like "Linux raspberrypi 6.12.37-v8+ #6 SMP PREEMPT Wed Dec 3 17:09:25 2025 aarch64 GNU/Linux".
Your modules will all have a similar signature.
If the two don't match then the kernel will refuse to load the module.
The config can be extracted by using "sudo modprobe configs" and copying /proc/config.gz. .version should have the value after the # in the output from uname -a, so 6 in my case.
Normally building additional modules would be done on the device rather than cross-compiled in order to avoid these sorts of issues.
(And yours aren't really out-of-tree as you're building them from the main Linux source tree, they just weren't in the default configuration)
The kernel you're running will report something like "Linux raspberrypi 6.12.37-v8+ #6 SMP PREEMPT Wed Dec 3 17:09:25 2025 aarch64 GNU/Linux".
Your modules will all have a similar signature.
If the two don't match then the kernel will refuse to load the module.
The config can be extracted by using "sudo modprobe configs" and copying /proc/config.gz. .version should have the value after the # in the output from uname -a, so 6 in my case.
Normally building additional modules would be done on the device rather than cross-compiled in order to avoid these sorts of issues.
(And yours aren't really out-of-tree as you're building them from the main Linux source tree, they just weren't in the default configuration)
Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Re: How to cross-compile kernel module?
Thank you for providing informations.
I tried few things and I'm still without success.
To match the kernel version used in the official Rpi Image, I cloned the Raspberry Pi Linux repo https://github.com/raspberrypi/linux.git and checkout to
359f37f0faefb712add32a39f98751aea67d5c1f
From Raspberry pi 5 I got .config file:
And copied it via SCP to my Ubuntu host machine.
Additionaly I copeid from /usr/src/liux-headers-6.12.47+rpt-rpi-2712/Module.symvers to my host machine also.
On the Raspberry I chechekd output of:
At the and I created .version file:
So at this point inside linux directory I have following:
Checkout to 359f37f0faefb712add32a39f98751aea67d5c1f
.config copied from running Rpi kernel
Module.symvers copied from running Rpi kernel
.version created based on 6.12.47+rpt-rpi-2712 #1
Inside .config I added modules that I want to add wit the flag "=m" to build them as modules
At the end I executed
I had successful build and copied modules and dtree to Rpi via SCP.
I checkend uname -a and the modinfo of the kernel module I just build, and they are the same.
Again I have symbol version mismatch.
Am I missing something else also?
Just fo my own curiosity, is tihs information correct?
I tried few things and I'm still without success.
To match the kernel version used in the official Rpi Image, I cloned the Raspberry Pi Linux repo https://github.com/raspberrypi/linux.git and checkout to
359f37f0faefb712add32a39f98751aea67d5c1f
From Raspberry pi 5 I got .config file:
Code: Select all
sudo modprobe configs
zcat /proc/config.gz > .configAdditionaly I copeid from /usr/src/liux-headers-6.12.47+rpt-rpi-2712/Module.symvers to my host machine also.
On the Raspberry I chechekd output of:
Code: Select all
uname -a
Linux raspberrypi 6.12.47+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.47-1+rpt1 (2025年09月16日) aarch64 GNU/Linux
Code: Select all
echo 1 > .versionCheckout to 359f37f0faefb712add32a39f98751aea67d5c1f
.config copied from running Rpi kernel
Module.symvers copied from running Rpi kernel
.version created based on 6.12.47+rpt-rpi-2712 #1
Inside .config I added modules that I want to add wit the flag "=m" to build them as modules
At the end I executed
Code: Select all
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbsI checkend uname -a and the modinfo of the kernel module I just build, and they are the same.
Again I have symbol version mismatch.
Am I missing something else also?
I also found information that official Raspberry Pi OS kernels contain two sets of patches:
Debian patches and Raspberry Pi–specific patches (from raspberrypi/linux)
This suggests that the upstream repo: https://github.com/raspberrypi/linux.git does not exactly match the kernel shipped in the official image.
Reference:
viewtopic.php?p=2210334#p2210334
Just fo my own curiosity, is tihs information correct?
- 6by9
- Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator - Posts: 18540
- Joined: Wed Dec 04, 2013 11:27 am
Re: How to cross-compile kernel module?
Sorry, this isn't something that I do, so I can't give any definitive steps.
modprobe does have --force-vermagic and --force-modversion to ignore the magic and version checking. Knowing which one it is complaining about would
It'd be worth comparing the vermagic line reported by "modinfo <file>" between the standard modules shipped and your modules.
modprobe does have --force-vermagic and --force-modversion to ignore the magic and version checking. Knowing which one it is complaining about would
Code: Select all
--force-vermagic
Every module contains a small string containing important
information, such as the kernel and compiler versions. If a
module fails to load and the kernel complains that the
"version magic" doesn't match, you can use this option to
remove it. Naturally, this check is there for your protection,
so using this option is dangerous unless you know what you're
doing.
This applies to any modules inserted: both the module (or
alias) on the command line and any modules on which it
depends.
--force-modversion
When modules are compiled with CONFIG_MODVERSIONS set, a
section detailing the versions of every interfaced used by (or
supplied by) the module is created. If a module fails to load
and the kernel complains that the module disagrees about a
version of some interface, you can use --force-modversion to
remove the version information altogether. Naturally, this
check is there for your protection, so using this option is
dangerous unless you know what you're doing.
This applies to any modules inserted: both the module (or
alias) on the command line and any modules on which it
depends.
-f, --force
Try to strip any versioning information from the module which
might otherwise stop it from loading: this is the same as
using both --force-vermagic and --force-modversion. Naturally,
these checks are there for your protection, so using this
option is dangerous unless you know what you are doing.
This applies to any modules inserted: both the module (or
alias) on the command line and any modules on which it
depends.Software Engineer at Raspberry Pi Ltd. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
I'm not interested in doing contracts for bespoke functionality - please don't ask.
Jump to
- Community
- General discussion
- Announcements
- Other languages
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- 日本語
- Polski
- Português
- Русский
- Türkçe
- User groups and events
- Raspberry Pi Official Magazine
- Using the Raspberry Pi
- Beginners
- Troubleshooting
- Advanced users
- Assistive technology and accessibility
- Education
- Picademy
- Teaching and learning resources
- Staffroom, classroom and projects
- Astro Pi
- Mathematica
- High Altitude Balloon
- Weather station
- Programming
- C/C++
- Java
- Python
- Scratch
- Other programming languages
- Windows 10 for IoT
- Wolfram Language
- Bare metal, Assembly language
- Graphics programming
- OpenGLES
- OpenVG
- OpenMAX
- General programming discussion
- Projects
- Networking and servers
- Automation, sensing and robotics
- Graphics, sound and multimedia
- Other projects
- Gaming
- Media centres
- AIY Projects
- Hardware and peripherals
- Camera board
- Compute Module
- Official Display
- HATs and other add-ons
- Device Tree
- Interfacing (DSI, CSI, I2C, etc.)
- Keyboard computers (400, 500, 500+)
- Raspberry Pi Pico
- General
- SDK
- MicroPython
- Other RP2040 boards
- Zephyr
- Rust
- AI Accelerator
- AI Camera - IMX500
- Hailo
- Software
- Raspberry Pi OS
- Raspberry Pi Connect
- Raspberry Pi Desktop for PC and Mac
- Beta testing
- Other
- Android
- Debian
- FreeBSD
- Gentoo
- Linux Kernel
- NetBSD
- openSUSE
- Plan 9
- Puppy
- Arch
- Pidora / Fedora
- RISCOS
- Ubuntu
- Ye Olde Pi Shoppe
- For sale
- Wanted
- Off topic
- Off topic discussion