If you’re taking a free embedded systems course and wondering why your board vendor ships a kernel that looks nothing like the one on kernel.org, you’re not alone. Choosing where your kernel comes from — and understanding what the GPL actually obligates you to do with it — are two of the most misunderstood decisions in embedded Linux development. This lecture, part of our free linux kernel development course, walks through both in plain language, with a hands-on demonstration of the GPL module-license mechanism you’ll use in every driver you write.
BSP
mainline Linux
GPL v2
MODULE_LICENSE
kernel module
free embedded linux course
What You Will Learn
How to evaluate a vendor BSP kernel
What GPL v2 actually requires from you
How MODULE_LICENSE works in practice
Writing a module that declares its license correctly
Prerequisites
You should be comfortable building and loading a basic out-of-tree kernel module, and understand roughly what a kernel version number means (covered in the earlier lectures of this free linux device drivers course). No prior legal knowledge is needed — everything here is explained from an engineer’s point of view, not a lawyer’s.
Why You Rarely Get a Kernel Straight From kernel.org
In principle you could clone Linus’s tree, pick a stable release, and boot it on any board. In practice, mainline Linux only has solid, well-tested support for a fraction of the silicon that exists. A brand-new SoC might have partial upstream support, or none at all, for months or years after it ships. Somebody has to write the clock drivers, pin controllers, power management code, and board-specific quirks before that hardware behaves properly under a generic kernel.
That “somebody” is usually one of three parties:
- The silicon vendor — they maintain a Board Support Package (BSP), a fork of some older kernel version patched heavily for their chip.
- An independent open-source project — groups like Linaro or the Yocto Project often upstream and maintain support that vendors haven’t gotten around to.
- The mainline community itself — for popular, well-supported platforms, everything you need may already be in kernel.org.
|
|– fully supported board? ———–> use mainline directly
|
|– partially supported? ————–> check Linaro / Yocto layers
|
|– vendor-only support? —————> use vendor BSP kernel
(evaluate quality first!)
Evaluating a Vendor BSP Kernel
Not all vendor kernels are equal. Some vendors carry a small, well-organized patch set on top of a recent mainline base and actively push their changes upstream. Others hand you a multi-thousand-patch fork of a kernel that was already old the day it shipped, with no intention of ever upstreaming anything. The second kind becomes a maintenance nightmare: security fixes never arrive, and every kernel upgrade means re-applying a mountain of vendor patches by hand.
When you’re choosing a board or SoC for a product, treat kernel support quality as a first-class selection criterion, on par with price and availability. A few questions worth asking before you commit:
| Question | Why It Matters |
|---|---|
| How large is the vendor’s patch set relative to mainline? | Smaller diffs are easier to rebase onto newer kernels |
| Does the vendor upstream any of their work? | Signals long-term commitment and code quality |
| How old is the kernel version the BSP is based on? | Older bases mean missing security fixes and features |
| Is there an active public git tree and issue tracker? | Indicates the BSP is a living project, not a dump |
Understanding GPL v2 Obligations for the Kernel
The Linux kernel is licensed under the GNU General Public License version 2 (GPL v2). The full license text ships in every kernel source tree in the COPYING file. In simple terms, GPL v2 says: if you distribute a modified version of a GPL-covered program, you must make the corresponding source code available to whoever you distributed the binary to.
Linus added an important clarification early on, included as an addendum in COPYING: code that merely calls into the kernel from user space through the normal system call interface is not considered a derivative work of the kernel. That’s why you can run proprietary applications on top of a GPL kernel without any licensing conflict — your app talks to the kernel through syscalls, it doesn’t link against kernel internals.
The Kernel Module Gray Area
Kernel modules sit in murkier territory. A module is dynamically linked into the kernel’s own address space at runtime and can call internal kernel functions directly — a much closer relationship than a user-space process calling read(). Strictly read, GPL v2 makes no distinction between static and dynamic linking, so a strong argument exists that module source falls under the GPL.
Over the years there have been exceptions and disputes — old filesystem code that predated Linux itself was argued to not be a “derivative work” — but the practical, widely accepted convention today is that the GPL does not automatically bind every out-of-tree module. This convention is codified directly in the kernel source through the MODULE_LICENSE() macro.
Declaring a Module’s License: A Working Example
Every kernel module should declare its license explicitly. This isn’t just a legal formality — the kernel actually checks it at load time. If you omit MODULE_LICENSE() or set it to something the kernel doesn’t recognize as free, you lose access to GPL-only exported symbols, and the kernel taints itself with a visible warning in dmesg.
Here’s a minimal, original demo module — ep_license_demo — that shows the difference in practice. First, a properly licensed GPL module:
// ep_license_demo.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init ep_license_demo_init(void)
{
pr_info("ep_license_demo: loaded, licensed under GPL\n");
return 0;
}
static void __exit ep_license_demo_exit(void)
{
pr_info("ep_license_demo: unloaded\n");
}
module_init(ep_license_demo_init);
module_exit(ep_license_demo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EmbeddedPathashala");
MODULE_DESCRIPTION("Demo module showing MODULE_LICENSE behaviour");
A minimal Makefile to build it against your running kernel’s headers:
obj-m += ep_license_demo.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Build and load it:
$ make
$ sudo insmod ep_license_demo.ko
$ dmesg | tail -n 3
Expected output — clean, no taint warning:
[ 1234.567890] ep_license_demo: loaded, licensed under GPL
Now change only the license string:
MODULE_LICENSE("Proprietary");
Rebuild and reload it, and you’ll see the kernel visibly object:
$ make
$ sudo insmod ep_license_demo.ko
$ dmesg | tail -n 3
[ 1300.112233] ep_license_demo: module license 'Proprietary' taints kernel.
[ 1300.112240] Disabling lock debugging due to kernel taint
[ 1300.112301] ep_license_demo: loaded, licensed under GPL
Notice the kernel is tainted — visible in cat /proc/sys/kernel/tainted — and if this module tried to call a symbol exported with EXPORT_SYMBOL_GPL() instead of the plain EXPORT_SYMBOL(), the load would fail outright with an “unknown symbol” error.
Real-World Use Case: Auditing a Vendor BSP
A common task for an embedded engineer joining a new project is auditing the vendor-supplied kernel for license hygiene before a product ships. A quick first pass:
$ grep -R "MODULE_LICENSE" drivers/ | grep -v "GPL" | grep -v "Dual"
This surfaces any out-of-tree or vendor modules claiming a non-GPL, non-dual license — worth flagging to legal/compliance review before mass production, since GPL source-disclosure obligations may apply to anything statically or dynamically linked into that kernel image.
Common Mistakes and Troubleshooting
- Forgetting
MODULE_LICENSE()entirely — the module still loads on most configurations but taints the kernel and triggers a build-time warning; always declare it. - Assuming a vendor’s old kernel is “free” just because it’s Linux — GPL obligations don’t expire; if you distribute a product with a modified kernel, source-disclosure obligations travel with it regardless of how old the base is.
- Confusing “open source” with “unmaintained is fine” — an ancient vendor BSP with no security backports is a liability even though the code is technically GPL-compliant.
- Mixing license strings inconsistently across a driver’s files — pick one license per module and be consistent; the kernel taint check applies per-module, not per-file.
Best Practices
- Prefer boards and SoCs with strong mainline or actively-upstreamed support wherever your product requirements allow it.
- Track the vendor’s patch delta against mainline over time — a shrinking delta is a good sign; a growing one is a warning.
- Always declare
MODULE_LICENSE()explicitly and correctly in every module you write. - Keep a bill-of-materials of every kernel module and its license in any product you ship, GPL or otherwise.
Security Considerations
Kernels forked far from mainline miss upstream security fixes unless someone actively backports them. Before choosing a vendor kernel, ask specifically how CVEs are tracked and backported for that BSP — “we rebase every two years” is a very different security posture than “we cherry-pick fixes weekly.”
Summary / Key Takeaways
- Mainline Linux doesn’t support every SoC — vendor BSPs, independent projects, or mainline itself fill the gap.
- Evaluate vendor kernels on patch size, upstreaming behavior, and base kernel age, not just feature checklists.
- GPL v2 covers the kernel itself; user-space syscall callers are exempt, but kernel modules are a debated gray area, conventionally handled via
MODULE_LICENSE(). - Declaring the wrong or missing license taints the kernel and can block access to GPL-only symbols.
Conclusion
Choosing a kernel source and understanding its licensing aren’t separate concerns from writing drivers — they shape which vendors you can safely build a product on and what obligations follow you to production. As you continue through this free linux development course, you’ll see this same GPL-awareness show up again whenever you write, package, or audit kernel code.
Frequently Asked Questions
Is a vendor BSP kernel always worse than mainline?
Not necessarily. Some vendors maintain high-quality BSPs with small, clean patch sets and active upstreaming. The problem is inconsistency across vendors — you have to evaluate each one individually.
Do I have to release my own kernel module’s source code?
If your module links against the kernel and you distribute the resulting binary, GPL v2 obligations likely apply unless you have a specific, well-argued exception. This is a legal question in edge cases — when in doubt, consult counsel rather than relying on convention alone.
What does “tainting” the kernel actually do?
A tainted kernel is flagged internally (visible via /proc/sys/kernel/tainted) and the kernel community may decline to help debug crash reports from a tainted system, since non-GPL or out-of-tree code could be the actual cause.
Can I use MODULE_LICENSE(“Dual BSD/GPL”)?
Yes — this is a recognized value indicating the code is available under either license, commonly used by drivers meant to be portable to BSD-licensed projects as well.
Does calling a syscall from my app make my app GPL?
No. Linus’s addendum in COPYING explicitly excludes normal syscall usage from being considered a derivative work of the kernel, which is why proprietary applications can run on Linux without licensing conflicts.
Where can I read the actual kernel license text?
It ships in every kernel source tree as the COPYING file at the top level — always the authoritative reference, not third-party summaries.
Continue the Free Linux Kernel Development Course
Next up: getting and building real kernel source code for your board.
