A MIPI camera driver is built against one kernel release, and multi-camera MIPI bundles often ship a support list that stops at 5.4.51-v7+ and 5.4.51-v7l+ — releases from July 2020. Nothing is wrong with the sensor: the kernel checks each module's vermagic string at load time and refuses anything that does not match. You have three moves, and this guide gives you the decision rule between them: pin the OS to the release the driver wants, rebuild the module from source against your running kernel headers, or sidestep the out-of-tree driver with a USB3 board camera. Either way you leave with the commands, the checks that prove the match, and the running cost of each choice.
Why does a MIPI camera driver only load on one kernel release?
Because the driver ships as an out-of-tree kernel module, and every module carries a vermagic string — release, architecture, build flags — that the running kernel checks at insert time: 5.4.51-v7l+ does not equal 5.15.x, so the loader rejects the file before your code runs.
The module was compiled against one kernel tree and links against the symbols that tree exports. At insert time the loader compares vermagic, and when the kernel is built with symbol versioning it also compares a checksum for every symbol the module uses. Same release, same architecture, same build options — all three or nothing loads. That is why a vendor list reads like a changelog frozen at 5.4.51-v7+ and 5.4.51-v7l+: the driver has not been rebuilt against other trees, so one OS update breaks a camera that worked the day before. The sensor is innocent; the load check refused your module.
A MIPI sensor has no generic class driver to fall back on. Its module registers the sensor as a V4L2 subdevice, and a device-tree overlay describes the wiring, which is why each bundle ships its own kernel module. Read the MIPI CSI camera connector pinout before you assume any camera is drop-in on a given board.
Should you pin the kernel or rebuild the driver module?
Pin when the driver is a validated part of a frozen, isolated image; rebuild when the device keeps taking kernel security updates. On the bench, rebuild; on a locked-down production cell, pin.
Four questions settle the rest:
- Is module source published? A binary-only module forces the pin. Published source turns the rebuild into a routine build job.
- Do security updates reach the device? An automatic update feed overwrites a pinned kernel within weeks of release. If updates flow, commit to the rebuild.
- What does requalification cost? On a line where every kernel change triggers revalidation, pinning plus network isolation is usually the cheaper contract.
- Who owns the build? If nobody can compile a kernel module today, the rebuild also means training, not just commands.
Decide once per project and write the decision down. Wavering is how machines end up half-pinned, with a held kernel and no record of why.
How do you pin the OS to the kernel release the driver needs?
Install the exact release your module's vermagic names — 5.4.51-v7l+ in the worked example below — then hold the kernel packages so no update moves them, and record the pin where the next image build will find it.
- Read the required release from the module file (shown here as
cam_driver.ko; substitute your driver's file name):modinfo cam_driver.ko | grep vermagic. A module from that supported list prints a line like5.4.51-v7l+ mod_unload ARMv7. Note the release and the architecture. - Install exactly that kernel release with the package manager. Debian-family distributions install an exact version with
package=version, so you can target the release whose name matches the vermagic string. - Hold the kernel packages:
sudo apt-mark holdplus each kernel package name, including the headers package if one is installed, so the pair cannot drift apart. - Exclude kernel origins from automatic upgrades, or check at every maintenance window that
uname -rstill equals the pinned release. - Write the pinned release into the image manifest, next to the driver version, so the next flash reproduces the pair exactly.
Reboot, run uname -r, and demand an exact match with the vermagic release before you call the camera working. Then load the module and read dmesg. If the module inserts but the sensor misbehaves, the device-tree overlay is the next suspect, not the kernel.
How do you rebuild the driver against your running kernel?
Install kernel headers that match uname -r to the patch level, build the vendor's module source against them with the standard kbuild command, and the rebuilt module carries your running release in its vermagic.
- Check what is running:
uname -r. Headers must match to the patch level, not just the major version. - Install the matching kernel headers from the distribution, because they carry the same build configuration as the shipped kernel. For a kernel released days ago the headers package can lag by several weeks; cloning the kernel source is then the current route to exact headers.
- Fetch the module source from the vendor's repository and take the branch nearest your running kernel.
- Build with the kbuild external-module invocation:
make -C /lib/modules/$(uname -r)/build M=$PWD modules. Its one precondition is a prebuilt kernel with the build directory present, which is exactly what the headers package installs. - Install the module, run
depmod -ato refresh the module index, then load it with modprobe.
The build takes minutes once headers are in place; the recurring cost is repeating it after every kernel update. On a fleet, put the module under DKMS so the rebuild runs automatically, and gate deployment on the vermagic check below.
How do you prove the module matches before you trust it?
Compare the module's vermagic with uname -r before anything else: they must agree release for release — 5.4.51-v7l+ against 5.4.51-v7l+ — and the classic Invalid module format message in dmesg is this comparison failing.
$ uname -r
5.15.32-v7l+ # example running release
$ modinfo cam_driver.ko | grep vermagic
vermagic: 5.4.51-v7l+ mod_unload ARMv7
Read the two lines as a comparison. 5.4.51 against 5.15.32 fails at the minor release, before architecture is even reached, and the loader answers with Invalid module format in dmesg. The clean fixes are the two sections above: pin uname -r to 5.4.51-v7l+, or rebuild so vermagic reads the running release. There is no clean third option. A module built for ARMv7 never inserts into an AArch64 kernel, whatever the release strings say. And with symbol versioning enabled, even a near-miss release fails on per-symbol checksums.
After the strings agree, prove the camera end to end: modprobe, a quiet dmesg, a /dev/video* node, and a raw frame grab before any application code. The camera module raw image capture check takes minutes and clears the driver before you debug your own software.
What does a frozen kernel cost you over a year?
Upstream support is the clock on a pin: kernel.org retired 5.4 from long-term support in December 2021, two years and one month after its November 2019 release, so a 5.4.51 pin now runs with no upstream security fixes.
After that date upstream stops shipping fixes while the pinned machine keeps running, and kernel vulnerabilities are published and indexed, so every USB port and network socket becomes a way in. A pin is a managed loan, not a permanent state: keep the cell offline or firewalled against outbound traffic, sign images so drift is visible, and put the rebuild date in the project plan. Before pinning at all, check how stale the vendor's newest supported release already is. Some bundle drivers stand still for more than a year after their last supported kernel, and that age is your best estimate of the stall ahead.
When is a USB3 board camera the cheaper answer?
If nobody owns the kernel and nobody owns the module build, change the camera instead of the OS: a USB3 board camera runs on the kernel's in-tree USB3 stack with a user-space library, so kernel updates stop being a camera problem.
MIPI ties the OS down because the sensor driver lives out of tree. USB3 moves the interface onto the camera: a bridge chip speaks standard USB3, the host side ships in the kernel tree, and vendor code runs as a user-space library that no kernel update touches. That is also why platforms with in-tree sensor support skip this decision entirely — see the built-in sensor driver support article — and why a USB3 bridge board must be matched before you stream when you wire your own. The UVC route on embedded Linux is the strongest form of this answer: a class driver, no vendor module at all.
Two USB3 board cameras that cover the common SBC inspection cases:
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 5 MP
- Sensor format
- 1/1.8"
- Interface
- USB3
- Resolution
- 6-10 MP
- Shutter
- Rolling
The LS-BCM-0003 covers motion work: 120 fps at 3.1 MP from a global-shutter sensor behind a C-mount. The MV-CB060-10UM-B covers detail work: 6 MP mono on a 1/1.8" rolling-shutter sensor, delivered as a bare board you build into your own housing — housing design from maker STEP files is the companion read for that path.
Which option should your line ship with?
Ship the pin for a binary-only module on an isolated, validated cell; ship the rebuild wherever security updates flow and someone owns the build; ship the USB3 camera when neither condition holds.
| Your situation | Decision | What you commit to |
|---|---|---|
| Binary-only module, validated image, isolated cell | Pin the kernel | Hold the exact release and re-check the hold every maintenance window |
| Module source published, updates flow, build owned | Rebuild the module | Headers and module rebuilt after every kernel update, vermagic checked automatically |
| Camera not yet fixed, no kernel owner on the team | Move to USB3 | A USB3 board camera: no out-of-tree module and no pin |
Before you order hardware, run the board camera evaluation checklist with the interface question first: MIPI buys you a driver to maintain, USB3 buys you a build to skip. The neighbouring bring-up guides sit on the cameras topic page. Compare the board-level cameras or open the camera finder, and the camera configurator walks lens, mount and interface next. If your build must stay on 5.4.51-v7l+ and you want a second opinion on the pin, message us — expert support comes with every order.
Questions
Can I force-load a module built for a different kernel?
Not reliably. A force flag skips only the vermagic string check; with symbol versioning enabled the per-symbol checksums still fail and the module does not resolve. A forced insert that does succeed taints the kernel, and any later crash points at your shortcut first. Rebuild instead — the build takes minutes once matching headers are installed.
Do I need module source from the camera vendor to rebuild?
Yes. A binary-only .ko cannot be retargeted to another kernel release, so a vendor that publishes only binaries leaves pinning as your only option. Vendors of open MIPI drivers usually publish module source in a public repository; confirm a branch exists near your kernel version before you commit to the rebuild path.
Will a driver built for 32-bit ARM load on a 64-bit kernel?
No. The architecture token in the module — ARMv7 versus AArch64 — must match the running kernel alongside the release string. A 64-bit OS needs the module rebuilt from source against 64-bit headers even when the version matches, so read both tokens in modinfo output before you build a product around an old image.
How long can I keep running a pinned old kernel?
Treat upstream dates as the budget. 5.4 shipped in November 2019 and left long-term support in December 2021, so any 5.4 pin now runs without security fixes. For an isolated cell with signed images that is a managed risk; for anything network-exposed, plan the rebuild within weeks rather than years.
What exactly must the kernel headers match?
The running kernel's release and its build configuration, not just the version number. Headers from a differently configured kernel produce symbol and configuration mismatches at load time even when the strings agree, which is why the distribution's own headers package is the right source for SBC module builds.
Does a USB3 camera remove the kernel module problem entirely?
For the module, yes in practice: the USB3 transport and UVC class handling live in the kernel tree, and vendor code ships as a user-space library no kernel update touches. Check the interface before you buy — a UVC-class or USB3 Vision device behaves this way, while a driver that inserts a kernel module does not.

