Linux 内核许可规则¶
Linux 内核仅根据 GNU 通用公共许可证第 2 版 (GPL-2.0) 的条款提供(如 LICENSES/preferred/GPL-2.0 中所述),并带有 COPYING 文件中所述的、在 LICENSES/exceptions/Linux-syscall-note 中描述的明确系统调用异常。
本文档文件描述了如何对每个源文件进行注释,以使其许可证清晰明确。它不能替代内核的许可证。
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 内核上运行的可执行文件的源文件中,因此该异常必须通过特殊的许可证表达式进行记录。
表达源文件许可证的常见方法是将相应的样板文本(boilerplate text)添加到文件的顶部注释中。由于格式、拼写错误等原因,这些“样板”对于用于许可证合规性上下文的工具来说很难验证。
替代样板文本的方法是在每个源文件中使用软件软件包数据交换 (SPDX) 许可证标识符。SPDX 许可证标识符是机器可解析的、精确的简写,用于表示贡献文件内容所依据的许可证。SPDX 许可证标识符由 Linux 基金会的 SPDX 工作组管理,并得到了整个行业的合作伙伴、工具供应商和法律团队的一致认可。有关更多信息,请参见 https://spdx.org/
Linux 内核要求所有源文件都使用精确的 SPDX 标识符。内核中使用的有效标识符在许可标识符一节中进行了说明,它们与许可证文本一起从官方 SPDX 许可证列表 https://spdx.org/licenses/ 中检索。
许可标识符语法¶
放置位置
内核文件中的 SPDX 许可证标识符应添加到文件中能够包含注释的第一行。对于大多数文件,这是第一行,但需要在第一行使用 `#!PATH_TO_INTERPRETER` 的脚本除外。对于这些脚本,SPDX 许可证标识符放在第二行。
如果需要,许可证标识符行后面可以跟随一个或多个 SPDX-FileCopyrightText 行。
样式
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++ 样式的注释。
语法
一个 <SPDX License Expression>(SPDX 许可证表达式)要么是 SPDX 许可证列表上找到的 SPDX 许可证简写标识符,要么是当适用许可证例外时,由 “WITH” 分隔的两个 SPDX 许可证简写标识符的组合。当适用多个许可证时,表达式由用关键字 “AND”、“OR” 分隔子表达式并用 “(”、“)” 包围的结构组成。
诸如带有“或更新版本”(or later)选项的 [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+
许可标识符¶
当前使用的许可证以及添加到内核的代码的许可证可细分为
首选许可证:
只要有可能,就应使用这些许可证,因为它们众所周知是完全兼容且被广泛使用的。这些许可证可从以下目录获取
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 textSPDX-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
已弃用的许可证
这些许可证只能用于现有代码或从不同项目导入代码。这些许可证可从以下目录获取
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
仅限双重许可证
这些许可证只能用于将代码与除首选许可证之外的另一个许可证进行双重许可。这些许可证可从以下目录获取
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
例外:
某些许可证可以通过例外进行修改,这些例外授予了原许可证所没有的某些权利。这些例外可从以下目录获取
LICENSES/exceptions/
在内核源码树中。此目录中的文件包含完整的例外文本和所需的例外元标签。
示例
LICENSES/exceptions/Linux-syscall-note
包含 Linux 内核 COPYING 文件中所记载的、用于 UAPI 头文件的 Linux 系统调用例外。例如 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
LICENSES/exceptions/GCC-exception-2.0
包含 GCC 的“链接例外”(linking exception),该例外允许将任何二进制文件(无论其许可证如何)与标记有此例外的文件的编译版本进行链接。这对于从与 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 textSPDX-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 不兼容”。此字符串专门用于与 GPL2 不兼容的第三方模块,不能用于其源代码位于内核树中的模块。以这种方式标记的模块在加载时会用 ‘P’ 标志污染内核,并且内核模块加载器拒绝将此类模块与使用
EXPORT_SYMBOL_GPL()导出的符号进行链接。