Linux 内核许可规则

Linux 内核仅根据 GNU 通用公共许可证版本 2(GPL-2.0)的条款提供,如 LICENSES/preferred/GPL-2.0 中所述,并具有 LICENSES/exceptions/Linux-syscall-note 中描述的明确的系统调用例外,如 COPYING 文件中所述。

此文档文件描述了如何注释每个源文件,以使其许可清晰明确。它不会取代内核的许可证。

COPYING 文件中描述的许可证适用于整个内核源代码,尽管单个源文件可以具有与 GPL-2.0 兼容的不同许可证。

GPL-1.0+  :  GNU General Public License v1.0 or later
GPL-2.0+  :  GNU General Public License v2.0 or later
LGPL-2.0  :  GNU Library General Public License v2 only
LGPL-2.0+ :  GNU Library General Public License v2 or later
LGPL-2.1  :  GNU Lesser General Public License v2.1 only
LGPL-2.1+ :  GNU Lesser General Public License v2.1 or later

除此之外,单个文件可以以双重许可证提供,例如,一种兼容的 GPL 变体,以及另一种诸如 BSD、MIT 等的宽松许可证。

用户空间 API (UAPI) 头文件,描述用户空间程序与内核的接口,是一个特例。根据内核 COPYING 文件中的说明,系统调用接口是一个明确的边界,不会将 GPL 要求扩展到任何使用它与内核通信的软件。由于 UAPI 头文件必须可以包含到任何在 Linux 内核上运行的可执行文件的源文件中,因此必须使用特殊的许可表达式记录该例外。

表达源文件许可的常用方法是在文件顶部注释中添加匹配的样板文本。由于格式、拼写错误等原因,这些“样板”很难使用在许可证合规性上下文中使用的工具进行验证。

样板文本的替代方法是在每个源文件中使用软件封装数据交换 (SPDX) 许可标识符。SPDX 许可标识符是机器可解析的,并且是文件内容贡献的许可证的精确简写。SPDX 许可标识符由 Linux 基金会的 SPDX 工作组管理,并已获得整个行业、工具供应商和法律团队的合作伙伴的同意。有关更多信息,请参见 https://spdx.org/

Linux 内核要求所有源文件中都包含精确的 SPDX 标识符。内核中使用的有效标识符在 许可标识符 部分中进行了解释,并已从 https://spdx.org/licenses/ 的官方 SPDX 许可列表中检索,以及许可文本。

许可标识符语法

  1. 放置

    内核文件中的 SPDX 许可标识符应添加到文件中可以包含注释的第一行。对于大多数文件,这是第一行,除了脚本需要在第一行中使用“#!PATH_TO_INTERPRETER”。对于这些脚本,SPDX 标识符放在第二行。


  1. 样式

    SPDX 许可标识符以注释的形式添加。注释样式取决于文件类型

    C source: // SPDX-License-Identifier: <SPDX License Expression>
    C header: /* SPDX-License-Identifier: <SPDX License Expression> */
    ASM:      /* SPDX-License-Identifier: <SPDX License Expression> */
    scripts:  # SPDX-License-Identifier: <SPDX License Expression>
    .rst:     .. SPDX-License-Identifier: <SPDX License Expression>
    .dts{i}:  // SPDX-License-Identifier: <SPDX License Expression>
    

    如果特定工具无法处理标准注释样式,则应使用该工具接受的适当注释机制。这就是在 C 头文件中使用“/* */”样式注释的原因。在使用生成的 .lds 文件时,观察到“ld”无法解析 C++ 注释的构建中断。这个问题现在已经修复,但仍然有一些较旧的汇编工具无法处理 C++ 样式注释。


  1. 语法

    <SPDX 许可表达式> 是在 SPDX 许可列表中找到的 SPDX 短格式许可标识符,或者是当许可证例外适用时,由“WITH”分隔的两个 SPDX 短格式许可标识符的组合。当适用多个许可证时,表达式由关键字 “AND”、“OR” 分隔子表达式并用 “(”、“)” 包围组成。

    对于像带有“或更高版本”选项的 [L]GPL 这样的许可证的许可标识符,通过使用 “+” 表示 “或更高版本” 选项来构造。

    // SPDX-License-Identifier: GPL-2.0+
    // SPDX-License-Identifier: LGPL-2.1+
    

    当需要对许可证进行修改时,应使用 WITH。例如,linux 内核 UAPI 文件使用表达式

    // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
    // SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note
    

    内核中发现的使用 WITH 例外的其他示例是

    // SPDX-License-Identifier: GPL-2.0 WITH mif-exception
    // SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0
    

    例外只能与特定的许可证标识符一起使用。有效的许可证标识符在例外文本文件的标签中列出。有关详细信息,请参见例外一章中的 许可标识符 点。

    如果文件是双重许可的并且仅选择一个许可证,则应使用 OR。例如,一些 dtsi 文件在双重许可下可用

    // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    

    内核中双重许可文件的许可表达式示例

    // SPDX-License-Identifier: GPL-2.0 OR MIT
    // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
    // SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
    // SPDX-License-Identifier: GPL-2.0 OR MPL-1.1
    // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT
    // SPDX-License-Identifier: GPL-1.0+ OR BSD-3-Clause OR OpenSSL
    

    如果文件具有多个许可证,其条款都适用于使用该文件,则应使用 AND。例如,如果代码是从另一个项目继承的,并且已获得将其放入内核的许可,但原始许可证条款需要保持有效

    // SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) AND MIT
    

    另一个需要遵守两组许可证条款的示例是

    // SPDX-License-Identifier: GPL-1.0+ AND LGPL-2.1+
    

许可标识符

当前使用的许可证以及添加到内核的代码的许可证可以分解为

  1. 首选许可证:

    应尽可能使用这些许可证,因为它们已知完全兼容并且被广泛使用。这些许可证可从目录中获取

    LICENSES/preferred/
    

    在内核源代码树中。

    此目录中的文件包含完整的许可证文本和 元标记。文件名与 SPDX 许可标识符相同,该标识符应用于源文件中的许可证。

    示例

    LICENSES/preferred/GPL-2.0
    

    包含 GPL 版本 2 许可证文本和所需的元标记

    LICENSES/preferred/MIT
    

    包含 MIT 许可证文本和所需的元标记

    元标记:

    以下元标记必须在许可证文件中可用

    • Valid-License-Identifier

      一行或多行,声明哪些许可证标识符在项目中有效,以引用此特定的许可证文本。通常,这是一个有效的标识符,但例如,对于具有“或更高版本”选项的许可证,两个标识符都是有效的。

    • SPDX-URL

      SPDX 页面的 URL,其中包含与许可证相关的其他信息。

    • Usage-Guidance

      用于使用建议的自由格式文本。文本必须包含 SPDX 许可证标识符的正确示例,因为它们应根据 许可标识符语法 指南放入源文件中。

    • License-Text

      此标记之后的所有文本均视为原始许可证文本

    文件格式示例

    Valid-License-Identifier: GPL-2.0
    Valid-License-Identifier: GPL-2.0+
    SPDX-URL: https://spdx.org/licenses/GPL-2.0.html
    Usage-Guide:
      To use this license in source code, put one of the following SPDX
      tag/value pairs into a comment according to the placement
      guidelines in the licensing rules documentation.
      For 'GNU General Public License (GPL) version 2 only' use:
        SPDX-License-Identifier: GPL-2.0
      For 'GNU General Public License (GPL) version 2 or any later version' use:
        SPDX-License-Identifier: GPL-2.0+
    License-Text:
      Full license text
    
    SPDX-License-Identifier: MIT
    SPDX-URL: https://spdx.org/licenses/MIT.html
    Usage-Guide:
      To use this license in source code, put the following SPDX
      tag/value pair into a comment according to the placement
      guidelines in the licensing rules documentation.
        SPDX-License-Identifier: MIT
    License-Text:
      Full license text
    

  1. 已弃用的许可证

    这些许可证仅应用于现有代码或从其他项目导入代码。这些许可证可从目录中获取

    LICENSES/deprecated/
    

    在内核源代码树中。

    此目录中的文件包含完整的许可证文本和 元标记。文件名与 SPDX 许可标识符相同,该标识符应用于源文件中的许可证。

    示例

    LICENSES/deprecated/ISC
    

    包含 Internet Systems Consortium 许可证文本和所需的元标记

    LICENSES/deprecated/GPL-1.0
    

    包含 GPL 版本 1 许可证文本和所需的元标记。

    元标记

    “其他”许可证的元标记要求与 首选许可证 的要求相同。

    文件格式示例

    Valid-License-Identifier: ISC
    SPDX-URL: https://spdx.org/licenses/ISC.html
    Usage-Guide:
      Usage of this license in the kernel for new code is discouraged
      and it should solely be used for importing code from an already
      existing project.
      To use this license in source code, put the following SPDX
      tag/value pair into a comment according to the placement
      guidelines in the licensing rules documentation.
        SPDX-License-Identifier: ISC
    License-Text:
      Full license text
    

  1. 仅双重许可

    这些许可证仅应用于使用另一种许可证(除了首选许可证)的双重许可代码。这些许可证可从目录中获取

    LICENSES/dual/
    

    在内核源代码树中。

    此目录中的文件包含完整的许可证文本和 元标记。文件名与 SPDX 许可标识符相同,该标识符应用于源文件中的许可证。

    示例

    LICENSES/dual/MPL-1.1
    

    包含 Mozilla 公共许可证版本 1.1 许可证文本和所需的元标记

    LICENSES/dual/Apache-2.0
    

    包含 Apache 许可证版本 2.0 许可证文本和所需的元标记。

    元标记

    “其他”许可证的元标记要求与 首选许可证 的要求相同。

    文件格式示例

    Valid-License-Identifier: MPL-1.1
    SPDX-URL: https://spdx.org/licenses/MPL-1.1.html
    Usage-Guide:
      Do NOT use. The MPL-1.1 is not GPL2 compatible. It may only be used for
      dual-licensed files where the other license is GPL2 compatible.
      If you end up using this it MUST be used together with a GPL2 compatible
      license using "OR".
      To use the Mozilla Public License version 1.1 put the following SPDX
      tag/value pair into a comment according to the placement guidelines in
      the licensing rules documentation:
    SPDX-License-Identifier: MPL-1.1
    License-Text:
      Full license text
    

  1. 例外:

    一些许可证可以使用例外进行修改,这些例外授予原始许可证不授予的某些权利。这些例外可从目录中获取

    LICENSES/exceptions/
    

    在内核源代码树中。此目录中的文件包含完整的例外文本和必需的 例外元标记

    示例

    LICENSES/exceptions/Linux-syscall-note
    

    包含 Linux 内核 COPYING 文件中记录的 Linux 系统调用例外,该例外用于 UAPI 头文件。例如,/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */

    LICENSES/exceptions/GCC-exception-2.0
    

    包含 GCC“链接例外”,允许将任何二进制文件(与其许可证无关)链接到使用此例外标记的文件的编译版本。这是从与 GPL 不兼容的源代码创建可运行的可执行文件所必需的。

    例外元标记:

    以下元标记必须在例外文件中可用

    • SPDX-Exception-Identifier

      一个可以与 SPDX 许可证标识符一起使用的例外标识符。

    • SPDX-URL

      SPDX 页面的 URL,其中包含与例外相关的其他信息。

    • SPDX-Licenses

      可以使用例外的一系列以逗号分隔的 SPDX 许可证标识符。

    • Usage-Guidance

      用于使用建议的自由格式文本。文本后面必须跟有 SPDX 许可证标识符的正确示例,因为它们应根据 许可标识符语法 指南放入源文件中。

    • Exception-Text

      此标记之后的所有文本均视为原始例外文本

    文件格式示例

    SPDX-Exception-Identifier: Linux-syscall-note
    SPDX-URL: https://spdx.org/licenses/Linux-syscall-note.html
    SPDX-Licenses: GPL-2.0, GPL-2.0+, GPL-1.0+, LGPL-2.0, LGPL-2.0+, LGPL-2.1, LGPL-2.1+
    Usage-Guidance:
      This exception is used together with one of the above SPDX-Licenses
      to mark user-space API (uapi) header files so they can be included
      into non GPL compliant user-space application code.
      To use this exception add it with the keyword WITH to one of the
      identifiers in the SPDX-Licenses tag:
        SPDX-License-Identifier: <SPDX-License> WITH Linux-syscall-note
    Exception-Text:
      Full exception text
    
    SPDX-Exception-Identifier: GCC-exception-2.0
    SPDX-URL: https://spdx.org/licenses/GCC-exception-2.0.html
    SPDX-Licenses: GPL-2.0, GPL-2.0+
    Usage-Guidance:
      The "GCC Runtime Library exception 2.0" is used together with one
      of the above SPDX-Licenses for code imported from the GCC runtime
      library.
      To use this exception add it with the keyword WITH to one of the
      identifiers in the SPDX-Licenses tag:
        SPDX-License-Identifier: <SPDX-License> WITH GCC-exception-2.0
    Exception-Text:
      Full exception text
    

所有 SPDX 许可证标识符和例外必须在 LICENSES 子目录中都有一个相应的文件。这是允许工具验证(例如,checkpatch.pl)并使许可证可以从源代码中直接读取和提取所必需的,这是各种 FOSS 组织(例如,FSFE REUSE 倡议)所推荐的。

MODULE_LICENSE

可加载内核模块也需要 MODULE_LICENSE() 标记。此标记既不能替代适当的源代码许可证信息 (SPDX-License-Identifier),也不能以任何方式用于表达或确定模块源代码提供的确切许可证。

此标记的唯一目的是为内核模块加载器和用户空间工具提供足够的信息,以确定模块是自由软件还是专有软件。

MODULE_LICENSE() 的有效许可证字符串是

“GPL”

模块在 GPL 版本 2 下获得许可。这并未表达 GPL-2.0-only 或 GPL-2.0-or-later 之间的任何区别。确切的许可证信息只能通过相应源文件中的许可证信息来确定。

“GPL v2”

与 “GPL” 相同。它的存在是出于历史原因。

“GPL 和其他权利”

表达模块源代码在 GPL v2 变体和 MIT 许可证下获得双重许可的历史变体。请不要在新代码中使用。

“Dual MIT/GPL”

正确表达模块以 GPL v2 变体或 MIT 许可选择双重许可的方式。

“双 BSD/GPL”

该模块以 GPL v2 变体或 BSD 许可选择双重许可。 BSD 许可的具体变体只能通过相应源文件中的许可信息确定。

“双 MPL/GPL”

该模块以 GPL v2 变体或 Mozilla 公共许可证 (MPL) 选择双重许可。 MPL 许可的具体变体只能通过相应源文件中的许可信息确定。

“专有”

该模块采用专有许可。“专有”仅理解为“该许可与 GPLv2 不兼容”。此字符串仅用于与 GPL2 不兼容的第三方模块,不能用于内核树中包含源代码的模块。以这种方式标记的模块在加载时会用 ‘P’ 标志污染内核,并且内核模块加载器会拒绝将此类模块链接到使用 EXPORT_SYMBOL_GPL() 导出的符号。