Skip to content

Packaging a Linux Driver

Overview

When a Linux driver is no longer just a lab experiment and starts becoming something that can be shared, reused, tested, or deployed, it should be packaged in a structured way.

A complete driver delivery usually includes more than just a kernel module.

Typical deliverables:

  • kernel module (.ko)
  • Device Tree overlay (.dtbo), if hardware binding is required
  • install / uninstall scripts
  • version information
  • release notes
  • usage instructions
  • compatibility notes

This note explains how to package a Linux driver in a practical and maintainable way.


1. What is a "driver package"?

A driver package is a release unit that contains everything required to deploy and use a driver on the target system.

For a Device Tree based platform such as Raspberry Pi, the package often includes:

  • driver binary (.ko)
  • overlay binary (.dtbo)
  • scripts to copy files into the correct system paths
  • instructions to load overlay and module
  • validation steps

Example:

mysensor-driver-v1.0.0/
├── README.md
├── RELEASE_NOTES.md
├── VERSION
├── i2c/
│   ├── mysensor_i2c_drv.ko
│   ├── mysensor-i2c.dtbo
│   ├── install.sh
│   └── uninstall.sh
└── spi/
    ├── mysensor_spi_drv.ko
    ├── mysensor-spi.dtbo
    ├── install.sh
    └── uninstall.sh

2. Why packaging matters

Packaging is important because a driver usually depends on more than code.

A user may need:

  • the module binary
  • the hardware description overlay
  • correct install path
  • correct load order
  • compatibility information

Without packaging, deployment becomes error-prone and difficult to reproduce.

A good package helps with:

  • repeatable installation
  • testing
  • release management
  • debugging
  • customer or team handoff

3. Core components of a driver package

3.1 Kernel module

The kernel module contains the driver logic.

Examples:

  • mysensor_i2c_drv.ko
  • mysensor_spi_drv.ko

This file is architecture- and kernel-version-dependent.

Important implication:

  • a .ko built for one kernel version may not work on another kernel version

3.2 Device Tree overlay

The overlay describes how the hardware should be instantiated.

Examples:

  • mysensor-i2c.dtbo
  • mysensor-spi.dtbo

Typical responsibilities:

  • enable bus controller
  • define sensor node
  • configure IRQ
  • disable conflicting default nodes such as spidev

Without the correct .dtbo, the driver may never probe.


3.3 Installation scripts

Install scripts reduce manual error and make deployment repeatable.

Typical tasks:

  • copy .ko into module path
  • copy .dtbo into overlay path
  • run depmod
  • optionally apply overlay and load module

3.4 Documentation

A useful driver package should include:

  • what the driver supports
  • target platform
  • kernel version used for validation
  • installation steps
  • removal steps
  • runtime verification commands

4. Binary package vs source package

There are two common ways to package a driver.

4.1 Binary package

Contains prebuilt files:

  • .ko
  • .dtbo

Advantages:

  • easy to install
  • quick deployment

Disadvantages:

  • tied to a specific kernel version and build environment

This is suitable when:

  • target platform is fixed
  • target kernel is fixed
  • deployment environment is controlled

4.2 Source package

Contains:

  • source code
  • Makefile
  • overlay source
  • build scripts

Advantages:

  • can rebuild against the target kernel
  • more flexible across system versions

Disadvantages:

  • requires toolchain and build steps

This is suitable when:

  • target kernel may vary
  • integration is handled by internal team or CI

5. Relationship between .ko and .dtbo

For Device Tree based drivers, .ko and .dtbo are often a matched pair.

The .ko provides the driver implementation.

The .dtbo provides the hardware instantiation and binding.

Example relationship:

mysensor_i2c_drv.ko  +  mysensor-i2c.dtbo
mysensor_spi_drv.ko  +  mysensor-spi.dtbo

The module alone is not enough if the device node is not created.

The overlay alone is not enough if the driver is not installed or loadable.

So, from a release point of view, they should be considered part of the same installation unit.


6. One package or multiple packages?

This depends on product structure.

6.1 One package with multiple variants

This is useful when the driver supports multiple transports for the same product family.

Example:

mysensor-driver-v1.0.0/
├── i2c/
└── spi/

Advantages:

  • one release version
  • one documentation set
  • easy comparison between variants

Recommended when:

  • same sensor family
  • same project
  • same release cadence

6.2 Separate packages

Example:

mysensor-i2c-driver-v1.0.0.tar.gz
mysensor-spi-driver-v1.0.0.tar.gz

Advantages:

  • simpler for end users
  • no confusion about which variant to install

Recommended when:

  • different teams own different variants
  • release schedules differ
  • customer only needs one transport

7. Version control strategy

Driver packaging needs version control at the project level, not just inside source files.

7.1 Project release version

This is the main release identifier.

Examples:

  • 0.1.0
  • 0.2.0
  • 1.0.0

This version should appear in:

  • release folder name
  • VERSION file
  • release notes
  • Git tag

Example:

mysensor-driver-v1.0.0
git tag v1.0.0

7.2 Module metadata version

Kernel module source may also include:

MODULE_VERSION("1.0.0");

This is useful for:

  • modinfo
  • module metadata visibility

But it is not sufficient as the main version control system.

It should be treated as a mirror of the release version, not the source of truth.


Recommended priority:

  1. Git tag
  2. VERSION file
  3. package name
  4. MODULE_VERSION()

8. Kernel compatibility

A kernel module is tightly coupled to the target kernel.

Important compatibility factors:

  • kernel version
  • architecture
  • config
  • vermagic
  • symbol versions

Therefore, a good release note should include a compatibility section.

Example:

Driver version: 1.0.0
Validated on:
- Raspberry Pi OS Lite
- Linux 6.12.47+rpt-rpi-2712
- ARM64

This avoids confusion when the module fails to load on a different system.


A practical release layout:

mysensor-driver-v1.0.0/
├── README.md
├── RELEASE_NOTES.md
├── VERSION
├── docs/
│   └── validation.md
├── i2c/
│   ├── mysensor_i2c_drv.ko
│   ├── mysensor-i2c.dtbo
│   ├── install.sh
│   └── uninstall.sh
└── spi/
    ├── mysensor_spi_drv.ko
    ├── mysensor-spi.dtbo
    ├── install.sh
    └── uninstall.sh

Optional additions:

  • checksums
  • sample config files
  • test utilities
  • known issue list

10. Example install workflow

10.1 I2C install

Typical steps:

sudo cp mysensor_i2c_drv.ko /lib/modules/$(uname -r)/extra/
sudo cp mysensor-i2c.dtbo /boot/firmware/overlays/
sudo depmod -a
sudo dtoverlay mysensor-i2c
sudo modprobe mysensor_i2c_drv

10.2 SPI install

Typical steps:

sudo cp mysensor_spi_drv.ko /lib/modules/$(uname -r)/extra/
sudo cp mysensor-spi.dtbo /boot/firmware/overlays/
sudo depmod -a
sudo dtoverlay mysensor-spi
sudo modprobe mysensor_spi_drv

11. Example uninstall workflow

Typical steps:

sudo modprobe -r mysensor_i2c_drv
sudo dtoverlay -r mysensor-i2c
sudo rm -f /lib/modules/$(uname -r)/extra/mysensor_i2c_drv.ko
sudo rm -f /boot/firmware/overlays/mysensor-i2c.dtbo
sudo depmod -a

The SPI variant follows the same idea.


12. Should install scripts modify config.txt?

There are two common strategies.

12.1 Runtime overlay loading

Example:

sudo dtoverlay mysensor-spi

Advantages:

  • cleaner for development
  • no persistent boot config pollution
  • easier to test and remove

Recommended for:

  • development
  • labs
  • debugging
  • bring-up

12.2 Boot-time configuration

Example:

dtoverlay=mysensor-spi

Advantages:

  • automatic load on boot
  • good for product deployment

Disadvantages:

  • modifies persistent system configuration
  • harder to experiment safely

Recommended for:

  • final product image
  • controlled deployment environment

13. What should install scripts validate?

A robust install script should verify:

  • target paths exist
  • copy succeeded
  • kernel version is compatible
  • overlay file is present
  • module file is present

Optional checks:

  • modinfo
  • dtoverlay -l
  • /sys/bus/*/devices
  • /sys/class/hwmon/hwmonX

14. Example package README content

A release README should answer these questions:

  • What does this package provide?
  • Which target platform was validated?
  • Which kernel version was used?
  • Which files should be installed?
  • How to enable the device?
  • How to verify successful probe?
  • How to uninstall it?

Example headings:

  • Overview
  • Package contents
  • Supported platforms
  • Installation
  • Verification
  • Removal
  • Known issues

15. Practical recommendations

Recommendation 1

Treat .ko and .dtbo as one logical delivery pair.


Recommendation 2

Keep I2C and SPI as separate install variants, even if they are released together.


Recommendation 3

Use Git tag + VERSION file as the main release version control.


Recommendation 4

Do not rely only on MODULE_VERSION() for release management.


Recommendation 5

Record exact kernel version used for validation.


Recommendation 6

For development stage, prefer runtime dtoverlay over editing config.txt.


16. Summary

Packaging a Linux driver is not just about copying a .ko file.

A proper driver package should include:

  • the module
  • the overlay
  • scripts
  • version information
  • compatibility notes
  • installation and validation instructions

For Device Tree based platforms, packaging should treat driver binary and hardware description as a matched pair.

A well-structured driver package improves maintainability, reproducibility, and deployment quality.


Suggested keywords

  • Linux driver packaging
  • kernel module release
  • Device Tree overlay deployment
  • driver installation workflow
  • binary driver package
  • release version control