Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

For a Linux driver meant to serve a broad range of users over the long term, aim to get it accepted into the kernel source tree if it can meet kernel licensing and contribution requirements. An out-of-tree module is a valid choice for experimental, product-specific, or schedule-constrained work—but your team must own compatibility with kernel changes, packaging, signing, and support.

What in-tree and out-of-tree mean

An in-tree driver is maintained within the Linux kernel source tree. An out-of-tree driver is developed or delivered separately and built as an external module against a configured kernel tree. Linux supports that external-module workflow through kbuild; it is not an unsupported workaround. The distinction is primarily about where the code is maintained and who takes responsibility for adapting it as the kernel evolves.

Neither placement guarantees a particular outcome. A mainline driver may not be enabled by every distribution, and upstream acceptance is not automatic. An external module can be the practical option when its target systems are controlled and someone is explicitly responsible for its ongoing maintenance.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose based on who will own compatibility

Decision factor In-tree Out-of-tree
Kernel-interface changes The driver can be updated alongside kernel changes, with maintainers and reviewers involved. Your team must track changes to internal interfaces and update and test the module for supported kernels.
Distribution and updates Distributions that enable the driver can ship it with their kernels, avoiding a separate download path for users. You control packaging and release timing, but must deliver updates and compatibility guidance separately.
Contribution and licensing Requires meeting kernel contribution rules and using a license compatible with GPLv2. May suit code that cannot currently be upstreamed, though legal obligations still depend on the code’s actual license and use.
Target-kernel control Useful when broad kernel and distribution reach is a goal; individual distributions still choose their configurations. Useful when the product controls its kernel versions and release cadence.
Deployment and support Users may avoid separate module installation, subject to distribution configuration and hardware support. You own external builds, packaging, signing requirements, troubleshooting, and user support.

Prefer in-tree for broad, durable support

In-tree is the stronger target when the driver is intended for general Linux users, the project can follow contribution and licensing requirements, and you want distributions that enable it to include it as part of their kernels. Kernel maintainers can adapt in-tree code when internal interfaces change. That does not eliminate maintenance or guarantee that a distribution will enable the driver, but it avoids leaving each user to find and match a separate module release.

Use out-of-tree for controlled or constrained work

An external module can make sense for prototypes, private product hardware, or delivery plans that cannot wait for upstream development. It also gives a vendor control over its own release cadence. That flexibility comes with a continuing obligation: define the kernel versions you support, test each relevant build, and provide a plan for updates when kernel internals change.

How external builds and loading affect deployment

Build against the target kernel

The kernel’s Building External Modules documentation describes the kbuild workflow. An external module is built against the relevant configured kernel tree, and during MODPOST kbuild uses Module.symvers to validate references to exported symbols. A build for one kernel is not evidence that the module will build or work with a later release. Kernel maintainers recommend using kbuild so modules use the appropriate build infrastructure and compiler flags.

For a product, make the build inputs and supported kernel versions part of the release process, rather than assuming a module binary is interchangeable across kernels. A makefile can hide much of the build detail from users, but it does not remove the need to build for the target kernel.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check module-signing policy before choosing delivery

Whether a separately built module loads can depend on the target kernel’s signature policy. Under restrictive enforcement, a module without a valid signature from a key trusted by that kernel is rejected. In permissive configurations, unsigned modules or modules signed by an unknown key may load, but the kernel is marked E-tainted. See the kernel’s module-signing documentation and confirm the policy on the systems you support.

Understand what taint does—and does not—mean

Loading an externally built module marks the kernel with the O taint flag. Taint records diagnostic context for kernel reports; it does not by itself show that the module caused a failure. Other flags are distinct: P indicates a proprietary module, and E indicates an unsigned module. The kernel’s tainted-kernels guide explains the flags and their diagnostic use.

Upstreaming depends on licensing and contribution rules

The kernel’s licensing rules describe GPL-2.0 as the kernel-wide license and set out source-license identification requirements. The MODULE_LICENSE tag is loader metadata: it tells the loader and tools whether a module is considered free software or proprietary, but it does not establish or replace the source code’s legal license. A proprietary-tagged module taints the kernel with P and cannot link against symbols exported with EXPORT_SYMBOL_GPL.

The kernel’s development introduction says contributions must use a license compatible with GPLv2 to be accepted. Upstreaming therefore is not simply a technical decision: the project must be able to contribute under compatible terms and work through the kernel’s development process. In return, the code can receive shared review and be maintained alongside changes that might otherwise break it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Rust drivers have the same placement trade-off

Rust does not remove the external-module compatibility problem. Rust for Linux’s out-of-tree module guidance says both C and Rust modules can be developed out of tree, while warning that Rust internal APIs may change at any time. Do not treat a project branch or current build as a promise of a stable external interface; plan for version-specific maintenance just as you would for an external C module.

A practical decision checklist

  • Choose in-tree as the goal if broad user reach, distribution integration, and shared adaptation to kernel changes matter—and the code can meet contribution and licensing requirements.
  • Choose out-of-tree if the driver is experimental or product-specific, upstream contribution is not currently feasible, or you control the target kernels and release schedule.
  • Name the maintenance owner for every supported kernel line; external code needs an explicit plan for tracking interface changes.
  • Verify deployment policy on target systems, including trusted signing keys, enforcement settings, and how users receive module updates.
  • Set user expectations about separate installation, supported kernel versions, and the diagnostic taint flags that may appear.

The kernel documentation notes that “The internal kernel API is in constant flux.” Its driver interface guidance explains why internal interfaces are not a stable contract for external code. The deciding question is therefore not just where the first version is easiest to build, but who can reliably maintain it across the kernel versions users will run.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.