Linux内核许可规则 【ChatGPT】

发布时间 2023-12-08 21:50:06作者: 摩斯电码

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通用公共许可证v1.0或更高版本
GPL-2.0+:GNU通用公共许可证v2.0或更高版本
LGPL-2.0:GNU库通用公共许可证仅限v2.0
LGPL-2.0+:GNU库通用公共许可证v2.0或更高版本
LGPL-2.1:GNU较低通用公共许可证仅限v2.1
LGPL-2.1+:GNU较低通用公共许可证v2.1或更高版本

除此之外,单个文件可以提供双重许可,例如兼容的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标识符放在第二行。

  2. 样式:

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

    C源代码:// SPDX-License-Identifier: <SPDX许可证表达式>
    C头文件:/* SPDX-License-Identifier: <SPDX许可证表达式> */
    汇编:/* SPDX-License-Identifier: <SPDX许可证表达式> */
    脚本:# SPDX-License-Identifier: <SPDX许可证表达式>
    .rst:.. SPDX-License-Identifier: <SPDX许可证表达式>
    .dts{i}:// SPDX-License-Identifier: <SPDX许可证表达式>
    

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

  3. 语法:

    <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:
      要在源代码中使用此许可证,请根据许可证规则文档中的放置指南,将以下 SPDX 标签/值对之一放入注释中。
      对于“GNU 通用公共许可证(GPL)第 2 版”,请使用:
    	SPDX-License-Identifier: GPL-2.0
      对于“GNU 通用公共许可证(GPL)第 2 版或任何更高版本”,请使用:
    	SPDX-License-Identifier: GPL-2.0+
    License-Text:
      完整的许可证文本
    
    SPDX-License-Identifier: MIT
    SPDX-URL: https://spdx.org/licenses/MIT.html
    Usage-Guide:
      要在源代码中使用此许可证,请根据许可证规则文档中的放置指南,将以下 SPDX 标签/值对放入注释中。
    	SPDX-License-Identifier: MIT
    License-Text:
      完整的许可证文本
    
  2. 已弃用的许可证:

    这些许可证应仅用于现有代码或从不同项目导入代码。这些许可证可以从内核源代码树中的目录中获取:

    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:
      不鼓励在内核中使用此许可证来编写新代码,应仅用于从已存在项目中导入代码。
      要在源代码中使用此许可证,请根据许可证规则文档中的放置指南,将以下 SPDX 标签/值对放入注释中。
    	SPDX-License-Identifier: ISC
    License-Text:
      完整的许可证文本
    
  3. 仅双重许可

    这些许可证应仅用于将代码与首选许可证以外的其他许可证进行双重许可。这些许可证可以从内核源代码树中的目录中获取:

    LICENSES/dual/
    

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

    示例:

    LICENSES/dual/MPL-1.1
    

    包含 Mozilla Public License 版本 1.1 许可证文本和所需的元标记:

    LICENSES/dual/Apache-2.0
    

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

    元标记:

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

    文件格式示例:

    SPDX-URL: https://spdx.org/licenses/MPL-1.1.html
    Usage-Guide:
      请勿使用。MPL-1.1 不与 GPL2 兼容。只能用于双重许可文件,其中另一个许可证与 GPL2 兼容。
      如果最终使用此许可证,必须与与 GPL2 兼容的许可证一起使用,使用“OR”。
      要使用 Mozilla Public License 版本 1.1,请根据许可证规则文档中的放置指南,将以下 SPDX 标签/值对放入注释中:
    SPDX-License-Identifier: MPL-1.1
    License-Text:
      完整的许可证文本
    
  4. 异常:

    某些许可证可以通过异常进行修改,以授予原始许可证不具备的某些权利。这些异常可以从内核源代码树中的目录中获取:

    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-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:
      此异常与上述 SPDX-Licenses 之一一起使用,用于标记用户空间 API(uapi)头文件,以便将其包含到不符合 GPL 的用户空间应用程序代码中。
      要使用此异常,请将其与 SPDX-Licenses 标签中的关键字 WITH 一起添加到其中一个标识符中:
    	SPDX-License-Identifier: <SPDX-License> WITH Linux-syscall-note
    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:
      “GCC Runtime Library exception 2.0”与上述 SPDX-Licenses 之一一起使用,用于从 GCC 运行时库导入的代码。
      要使用此异常,请将其与 SPDX-Licenses 标签中的关键字 WITH 一起添加到其中一个标识符中:
    	SPDX-License-Identifier: <SPDX-License> WITH GCC-exception-2.0
    Exception-Text:
      完整的异常文本
    

所有 SPDX 许可证标识符和异常都必须在 LICENSES 子目录中具有相应的文件。这是为了允许工具验证(例如 checkpatch.pl),并且可以直接从源代码中读取和提取许可证,这是各种自由/开源软件组织(例如 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 Public License(MPL)选择。确切的 MPL 许可证变体只能通过相应源文件中的许可信息确定。
"Proprietary" 模块使用专有许可。此字符串仅适用于专有第三方模块,不能用于具有其源代码在内核树中的模块。标记为此方式的模块在加载时会使内核带有“P”标志,并且内核模块加载程序会拒绝将这些模块与使用 EXPORT_SYMBOL_GPL() 导出的符号进行链接。