What You Actually Owe: Open-Source License Obligations in Shipped Embedded Firmware

Open-Source License Obligations in Shipped Embedded Firmware

Every embedded Linux product ships with open-source software. The 2025 Open Source Security and Risk Analysis report found that 97 percent of commercial codebases contain open-source components. For embedded firmware specifically, the number is effectively 100 percent: the Linux kernel is GPL-2.0-only, BusyBox is GPL-2.0, U-Boot is GPL-2.0, glibc is LGPL-2.1, OpenSSL is Apache-2.0. Before the firmware team has written a single line of proprietary code, the product already carries a set of license obligations that must be fulfilled before the firmware ships to a customer.

Most embedded teams know this in principle and underestimate it in practice. The obligations are specific, the enforcement is real, and the consequences of non-compliance have become material. In February 2024, the Paris Court of Appeal ordered Orange S.A. to pay over €900,000 for distributing a modified version of the Lasso GPL-licensed authentication library without providing the required corresponding source code. In June 2024, AVM — one of Europe's largest router manufacturers — was ordered to pay legal costs after an individual developer successfully sued them for LGPL violations in their FRITZ\!Box firmware. In the United States, the Software Freedom Conservancy's case against Vizio survived a summary judgment motion in 2024, with the court ruling that consumers have standing to enforce the GPL as third-party beneficiaries. These are not hypothetical risks.

The practical implication for product teams is that open-source license compliance is a legal obligation with specific, actionable requirements, and the firmware architecture and build system must be designed to fulfill them — not as an afterthought before a release, but as a continuous property of the development process.

The Three License Categories That Matter for Embedded Firmware

Open-source licenses in embedded firmware fall into three categories that create meaningfully different obligations.

Permissive licenses — MIT, BSD-2-Clause, BSD-3-Clause, Apache-2.0 — allow use in proprietary commercial products with minimal restrictions. MIT and BSD require including the copyright notice and license text with any distribution. Apache-2.0 adds a requirement to include a NOTICE file if the original project provides one, and requires providing a copy of the Apache-2.0 license text. Apache-2.0 also includes an explicit patent license grant from contributors and a patent retaliation clause that terminates the license if the recipient initiates patent litigation against the licensor. For embedded firmware, these obligations are straightforward: bundle the license texts and copyright notices in the firmware package, or make them accessible through the device's interface.

Weak copyleft licenses — LGPL-2.1, LGPL-3.0, MPL-2.0 — require releasing source code and modifications for the licensed library itself, but do not require releasing proprietary application code that uses the library through its public API. LGPL-2.1 creates the additional requirement that the end user must be able to replace the LGPL library with a modified version — which in practice means the library must be linked dynamically, or the product must provide a mechanism for replacing the static library. LGPL components are pervasive in embedded Linux: glibc (the standard C library), libstdc++, libpthread, and many other foundational libraries are LGPL-licensed. The linking method — static versus dynamic — is the key technical decision that determines whether the LGPL's copyleft effect extends to proprietary application code compiled against these libraries.

Strong copyleft licenses — GPL-2.0, GPL-3.0, AGPL-3.0 — require that any derivative work distributed in binary form must be accompanied by (or followed by a written offer for) the complete corresponding source code. For GPL-2.0, the source code offer must remain valid for at least three years. For GPL-3.0, additional requirements apply: the recipient must receive installation information sufficient to install the software on the device (which affects products with secure boot or signed firmware requirements), and anti-tivoization provisions prohibit using technical measures to prevent users from running modified versions. AGPL-3.0 extends the copyleft trigger to network-accessible services — software accessed through a network interface is treated as a distribution, requiring source code availability even when no binary is physically transferred. AGPL components in embedded devices with network interfaces require the same source disclosure obligations as physical distribution.

Can your firmware pass an open-source compliance audit before it ships?

The GPL Copyleft Boundary — What It Does and Does Not Reach

The most consequential question in embedded firmware licensing is where the GPL's copyleft effect stops. The GPL requires that derivative works be distributed under the same license terms. Whether a proprietary firmware component constitutes a derivative work of a GPL component it interacts with is a question that has generated substantial legal and technical discussion, and the answer depends on the nature of the interaction.

The Linux kernel is GPL-2.0-only with a specific exception: user-space applications that interact with the kernel through the system call interface are not considered derivatives of the kernel. This kernel syscall exception is a deliberate policy of the kernel maintainers, not an inherent property of GPL-2.0. It means that a proprietary application running on Linux, communicating with the kernel through standard system calls, does not inherit the GPL-2.0 copyleft requirement. The firmware's proprietary application code can remain proprietary.

Kernel modules are a different matter. A loadable kernel module that is compiled against kernel headers, uses kernel internal APIs, and runs in kernel space is generally considered to be a derivative of the kernel by the Linux kernel community, even if it is loaded dynamically. Distributing a proprietary out-of-tree kernel module alongside a GPL-2.0 kernel creates legal risk that many legal teams advise against. The practical approaches are: upstream the driver to avoid this entirely, dual-license the module, use the DKMS pattern with user-space firmware loading rather than a kernel module, or use a user-space driver framework such as VFIO or UIO that moves device-specific logic to user space where the syscall exception applies.

Static linking of a proprietary application against a GPL library — compiling the library's object code directly into the proprietary binary — is the clearest path to GPL contamination. The resulting binary contains both GPL code and proprietary code, making separation impossible and the derivative work claim unambiguous. This is why avoiding GPL libraries in the dependency chain of proprietary application code is a firm architectural rule in commercially responsible embedded firmware development. It is also why GPL components in userspace — BusyBox being the most common — must be audited as a compilation dependency that could infect proprietary code linked against it.

The distinction between static and dynamic linking matters for LGPL. Dynamically linking a proprietary application against an LGPL library — the application and the library are separate files, the library is resolved at runtime by the dynamic linker — generally satisfies the LGPL's "ability to replace the library" requirement. The user can replace the shared library file with a modified version and the application will use the modified version. Statically linking an LGPL library into a proprietary binary eliminates this replaceability and triggers the LGPL's requirement to make the application's object code available so that users can relink against a modified library.

On deeply embedded platforms without a shared library infrastructure, static linking is the default because there is no dynamic linker. A bare-metal application or RTOS firmware that statically incorporates LGPL components without providing the application object files for relinking is in violation of LGPL-2.1. Teams building on FreeRTOS or Zephyr — both MIT-licensed RTOS kernels that encourage this usage — occasionally include LGPL components from external libraries that introduce this problem without the team recognizing it. The MIT license of the RTOS does not protect the firmware from the obligations of LGPL components the firmware incorporates.

What Fulfilling GPL Obligations Actually Requires

GPL compliance for shipped embedded firmware has specific technical deliverables that must be produced and made accessible. Knowing what they are in principle is insufficient — the build system must be structured to produce them, and the distribution method must make them accessible to recipients.

The complete corresponding source code (CCSC) is the primary GPL-2.0 deliverable. CCSC means all the source code used to build the GPL-licensed components in the shipped binary: the kernel source, the kernel configuration (.config), the compiler and build scripts needed to reproduce the binary from the source, and any patches the firmware team applied to the upstream components. An unmodified copy of the upstream source tarball is not CCSC if the firmware team applied patches — the patched source must be provided. The kernel .config is specifically required because it determines which kernel features are compiled in, and without it the recipient cannot reproduce the specific binary.

The GPL-2.0 allows two distribution methods for CCSC: including a physical copy with the binary distribution, or providing a written offer (valid for at least three years) to provide the source on a physical medium upon request. Most commercial embedded products use the written offer method, providing either a URL to a source repository or a statement on the product's documentation offering the source upon written request. The URL method is operationally simpler but requires that the URL remain valid and the source remain available for the duration of the written offer period — three years minimum, or the product's service lifetime if longer for GPL-3.0.

The license text itself must be included. GPL-2.0 section 1 requires that any distribution of the program includes a copy of the license. For a firmware binary, this typically means including the GPL-2.0 license text in the firmware package or making it accessible through the device's user interface or documentation. Products that ship with embedded web interfaces can satisfy this by making the license texts accessible through the interface. Products without any user interface must include the license texts in accompanying documentation.

Copyright notices must be preserved. GPL-2.0 requires that copyright notices be preserved in the source code and that they not be removed from distributed copies. This is a specific obligation per copyright holder, not a generic acknowledgment. A firmware binary that strips all copyright comments from source files during the build process and distributes the binary without any copyright notice preservation is violating GPL-2.0 even if it provides the source code, because the copyright notices have been removed from the distributed binary.

For GPL-3.0, the installation information requirement adds a significant practical burden for products with secure boot. If the firmware enforces cryptographic verification of code at startup — which is increasingly required by security standards and EU Cyber Resilience Act compliance requirements — GPL-3.0 requires providing the information necessary for the user to install a modified version and have it run on the device. This means providing the signing key, or a mechanism to add user keys, or using a key that the user controls. Products that use a manufacturer-controlled key for secure boot and distribute GPL-3.0 components (Linux kernel with GPL-3.0 licensed modules) are in tension with the installation information requirement. The Linux kernel itself is GPL-2.0-only, which does not carry this requirement, but GPL-3.0 modules or applications linked against GPL-3.0 libraries can trigger it.

Building Compliance Into the Build System

The most common failure mode in embedded firmware license compliance is treating it as a release-time checklist rather than a build-system property. A compliance approach that depends on a developer manually reviewing license obligations before each release will miss transitive dependencies, miss changes introduced by BSP updates, and create institutional knowledge that leaves with the engineer who last did the review.

Yocto and OpenEmbedded provide integrated tooling that makes build-time license compliance automatic. Every recipe in Yocto includes a LICENSE field specifying the component's license, and the OpenEmbedded build system collects these declarations and generates a license manifest — a complete inventory of every component in the image and its declared license — as a build artifact alongside the firmware image. The cve-check class extends this with vulnerability scanning against the NVD database. The create-spdx class, enabled by default in recent Yocto LTS releases, generates an SPDX-format Software Bill of Materials (SBOM) that captures package names, versions, license declarations, and source locations for every component in the build.

For COPYLEFT_LICENSE_AVAILABLE and related variables, Yocto can be configured to automatically archive the source code of all GPL and LGPL components into a tarball that ships alongside the firmware image. Setting ARCHIVER_CLASS = "archive-original" and configuring ARCHIVE_PACKAGE_SOURCE in the Yocto distro configuration produces a source archive that can be published as the CCSC deliverable required by GPL without requiring any manual intervention. This automation ensures that the source archive stays synchronized with the firmware binary — the most common compliance defect in manually maintained source archives is version mismatch between the offered source and the shipped binary.

For Buildroot-based embedded Linux projects, Buildroot provides the make legal-info target that collects all component licenses, license texts, and source archives into a legal/ directory in the build output. Running make legal-info as part of the CI/CD pipeline produces the compliance artifacts automatically with each build.

For RTOS and bare-metal firmware built outside of a Linux build system — Keil MDK, IAR, CMake, or vendor-specific build systems — the compliance tooling infrastructure is less mature. Software Composition Analysis (SCA) tools such as Black Duck, FOSSA, and REUSE — the REUSE tool from the FSFE specifically addresses license and copyright compliance in source repositories — can scan the dependency graph and detect license declarations. The SPDX identifier standard, which embeds machine-readable license identifiers as structured comments in source files (SPDX-License-Identifier: MIT), supports automated tooling detection even in codebases without package management.

SBOM and the Regulatory Dimension

The EU Cyber Resilience Act, which entered into force in 2024 with compliance becoming mandatory for most product categories in 2027, requires manufacturers to provide a Software Bill of Materials as part of the technical documentation for products with digital elements. The SBOM must identify all software components including open-source components with their version information. This regulatory requirement makes what was previously a best practice — maintaining a comprehensive component inventory — a legal obligation for products sold in European markets.

The SBOM dual-format approach has emerged as practical guidance for embedded manufacturers: CycloneDX JSON for CRA compliance (CycloneDX has a native firmware component type and built-in support for VEX vulnerability exploitability status documentation) and SPDX for open-source license compliance (SPDX is Yocto's native output and excels at license and copyright tracking). Generating both from the build system and maintaining them as versioned artifacts alongside each firmware release satisfies both the license compliance documentation requirement and the CRA SBOM obligation.

The SBOM as a living document matters more than the SBOM as a snapshot. A firmware image that receives security patches — which is now a regulatory obligation under the CRA — changes its component versions over time. An SBOM generated at initial product release that is never updated misrepresents the deployed software within months. The SBOM must be regenerated on every firmware build and version-controlled alongside the firmware binary, so that the component inventory and license obligations for each deployed firmware version are precisely known.

The CRA's SBOM requirement also extends to component suppliers: manufacturers are expected to obtain SBOMs from ODM manufacturers of embedded components and SoC vendors whose firmware blobs are incorporated into the final product. A manufacturer who receives a vendor-supplied binary blob for an NPU or wireless chipset firmware and ships it without any component inventory for that blob is unable to fully satisfy the CRA's transparency requirements for that component. This creates downstream pressure on the supply chain to provide SBOMs for embedded firmware components, which is aligning the commercial incentives with the compliance requirements.

embedded Linux

License Compatibility and Architectural Decisions

License compatibility constraints should inform firmware architecture decisions, not be resolved by architecture exceptions at release time. The most important constraint for commercial embedded firmware is the GPL-proprietary compatibility gap: GPL-2.0 code and proprietary code cannot be combined in the same binary without the proprietary code becoming subject to GPL-2.0. This is not a theoretical concern — it directly affects which components can be statically linked together and which must be isolated.

The practical architectural rules that follow from this are:

  • GPL components must be separated from proprietary components at process or module boundaries. On an embedded Linux system, user-space applications running in separate processes with GPL-licensed tools (BusyBox shell scripts, GPL command-line utilities) in separate processes do not infect each other through the process isolation boundary. A proprietary application that forks a BusyBox process to run a shell script does not become a GPL derivative because the interaction is through process boundaries, not compilation.
  • LGPL libraries should be linked dynamically where the platform supports it, or application object code must be made available for relinking where static linking is unavoidable. On constrained RTOS platforms, the alternative is to substitute the LGPL component with an MIT or Apache-licensed equivalent: uClibc-ng (LGPL) versus musl (MIT) as the C library, or WolfSSL (dual GPL/commercial) versus Mbed TLS (Apache-2.0) as the TLS library. These substitutions eliminate the LGPL linking obligation and simplify compliance.
  • Apache-2.0 and GPL-2.0 are incompatible when combined in the same binary. Apache-2.0's patent termination clause imposes an additional restriction that GPL-2.0 does not permit. This means an Apache-2.0 library cannot be statically linked into a GPL-2.0 binary. Apache-2.0 is compatible with GPL-3.0. For firmware teams that use both Apache-licensed middleware and GPL-2.0 kernel-adjacent code, the separation must be maintained at the binary level.
  • The license compatibility matrix that should be maintained as a project document — not held in the memory of the senior engineer — maps the license of every component to the components it can and cannot be combined with. This document drives the architectural decisions about linking models, process boundaries, and component substitutions. Treating it as a living document updated whenever a new dependency is introduced, rather than as a static reference, ensures that compatibility issues are caught at integration time rather than discovered during a legal audit.

Quick Overview

Embedded firmware license compliance is a legal obligation with specific technical deliverables, not a courtesy. GPL-2.0 requires complete corresponding source code — patched source, kernel .config, and build scripts — distributed with or offered alongside every shipped binary. LGPL-2.1 requires either dynamic linking or provision of application object files for relinking, which directly affects architectural decisions about shared versus static libraries. MIT, BSD, and Apache-2.0 require preserving copyright notices and license texts in distributed firmware. The 2024 enforcement actions — €900,000 damages against Orange, legal cost award against AVM — confirm that these obligations are enforced against commercial embedded product makers. EU Cyber Resilience Act requirements for SBOM generation, mandatory for most product categories by 2027, add a regulatory layer requiring a continuously maintained component inventory. Yocto's create-spdx class and ARCHIVER_CLASS configuration automate the production of SBOM and source archives as build artifacts, making compliance a build-system property rather than a release-time task.

Key Applications

Industrial and IoT embedded Linux products where GPL-2.0 kernel and BusyBox obligations require providing complete corresponding source code for each firmware version, automotive infotainment and ADAS platforms using LGPL glibc and libstdc++ that require dynamic linking verification or object file provision, medical device firmware subject to compliance audits where undisclosed open-source components create regulatory as well as legal risk, and any product undergoing M&A due diligence where undisclosed copyleft dependencies affecting proprietary IP are a valuation risk.

Benefits

Build-system automation of SBOM and source archive generation eliminates version mismatch between offered source and shipped binary, the most common technical defect in GPL compliance programs. Architectural separation of GPL components at process boundaries protects proprietary application code from copyleft contamination without restricting access to GPL functionality. Proactive LGPL linking architecture decisions — dynamic linking or MIT/Apache-licensed substitutes — eliminate the most complex LGPL compliance scenarios before they become problems. SPDX SBOM output from Yocto satisfies both open-source license compliance documentation and EU CRA SBOM requirements with one toolchain.

Challenges

GPL-3.0's installation information requirement is in direct tension with secure boot architectures that use manufacturer-controlled signing keys, requiring either providing signing keys to users, supporting user key enrollment, or avoiding GPL-3.0 components in products with enforced secure boot. Vendor-supplied binary blobs — NPU firmware, WiFi firmware, GPU firmware — often have no SBOM and unknown license obligations, creating compliance gaps that cannot be resolved without the vendor's cooperation. Static linking on RTOS and bare-metal platforms is the default because there is no dynamic linker, creating LGPL obligations that require architectural attention when LGPL components are introduced. Apache-2.0 and GPL-2.0 cannot be combined in the same binary, requiring strict separation for firmware that uses both.

Outlook

Open-source license enforcement is becoming a sustained commercial activity, not just idealistic community action. The SFC v. Vizio precedent establishing consumer standing to enforce GPL as third-party beneficiaries creates a plaintiff class that extends beyond open-source advocacy organizations to product customers. CRA SBOM requirements and ISO/IEC 5230 (OpenChain) certification for open-source compliance programs are establishing compliance as a commercially expected attribute, relevant to procurement, M&A, and enterprise contracts. The convergence of security vulnerability management and license compliance into the SBOM as a shared artifact — since both require the same component inventory — is driving adoption of automated SBOM generation in embedded firmware build pipelines faster than either concern would have driven it independently.

Related Terms

GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, AGPL-3.0, MPL-2.0, copyleft, strong copyleft, weak copyleft, permissive license, complete corresponding source code, CCSC, installation information, anti-tivoization, static linking, dynamic linking, kernel syscall exception, kernel module, license compatibility, SBOM, SPDX, CycloneDX, Software Bill of Materials, Yocto create-spdx, ARCHIVER_CLASS, cve-check, REUSE, FOSSA, Black Duck, SCA, SFC v. Vizio, BusyBox GPL enforcement, Cyber Resilience Act, OpenChain, ISO 5230, license manifest, copyright notice, written offer, source repository, uClibc-ng, musl, Mbed TLS, WolfSSL

 

 

Our Case Studies

 

FAQ

What source code must an embedded firmware team provide to comply with GPL-2.0?

 

GPL-2.0 requires the complete corresponding source code used to produce the distributed binary: the component's source files in the state that was compiled (including any patches applied), the kernel configuration file (.config for Linux kernel components), and the scripts and build environment needed to reproduce the binary from the source. An unpatched upstream tarball does not satisfy this obligation if the firmware team applied modifications. The source must be provided either alongside the binary distribution, as a physical copy, or through a written offer valid for at least three years directing recipients to the source. A public repository URL satisfies the written offer if it remains valid for the required period.

 

Why does static versus dynamic linking matter for LGPL compliance in embedded firmware?

 

LGPL-2.1 requires that end users be able to replace the LGPL-licensed library with a modified version and have the application use the modified version — the "ability to replace the library" requirement. Dynamic linking satisfies this because the application resolves the library at runtime from the filesystem, and replacing the library file achieves the requirement. Static linking incorporates the library's object code into the application binary, making replacement impossible without the application's own object code for relinking. For statically linked LGPL components, the team must provide the application's object files (not source code, specifically object files) so that users can relink against a modified library. On RTOS and bare-metal platforms without shared library infrastructure, this obligation applies whenever LGPL components are included.

 

Does the GPL copyleft extend from a Linux kernel module to the rest of the firmware?

 

The Linux kernel community's position is that loadable kernel modules using kernel internal APIs in kernel space are derivative works of the kernel and subject to GPL-2.0. A proprietary out-of-tree kernel module distributed alongside a GPL-2.0 kernel carries legal risk that most legal teams treat as a violation. The copyleft effect does not extend beyond the kernel boundary to user-space applications that interact with the kernel through standard system calls — the kernel maintainers explicitly exempted this via the kernel syscall exception. A proprietary user-space daemon communicating with a kernel module through ioctl or sysfs does not become GPL through that interaction.

 

How does the Yocto build system support license compliance automation?

 

Yocto collects license declarations from every recipe's LICENSE field and generates a license manifest as a build artifact. The create-spdx class, inherited by default in recent LTS releases, generates an SPDX-format SBOM covering all packages and their license declarations. Setting ARCHIVER_CLASS = "archive-original" or "archive-patched" configures the build to automatically archive source code for copyleft components, producing the complete corresponding source archive required for GPL compliance without manual intervention. The cve-check class extends this with CVE scanning against the NVD database. All these artifacts are generated alongside each firmware build image in the tmp/deploy directory.