Linux 内核许可规则

Linux 内核根据 GNU 通用公共许可证第 2 版(GPL-2.0)的条款提供,详见 LICENSES/preferred/GPL-2.0 文件;并附带在 LICENSES/exceptions/Linux-syscall-note 中描述的明确的系统调用(syscall)例外,如 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 标识符。内核中使用的有效标识符在许可标识符一节中解释,并已从官方 SPDX 许可证列表 https://spdx.org/licenses/ 以及许可证文本中获取。

许可标识符语法

  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 and additional rights”

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

“Dual MIT/GPL”

表示模块在 GPL v2 变体或 MIT 许可证选择下双重许可的正确方式。

“Dual BSD/GPL”

模块在 GPL v2 变体或 BSD 许可证选择下双重许可。BSD 许可证的确切变体只能通过相应源文件中的许可证信息来确定。

“Dual MPL/GPL”

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

“Proprietary”

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