2. SoC 子系统

2.1. 概述

SoC 子系统是 SoC 特定代码的聚合地。该子系统的主要组成部分是:

  • 用于 32 位和 64 位 ARM 以及 RISC-V 的设备树

  • 32 位 ARM 板级文件 (arch/arm/mach*)

  • 32 位和 64 位 ARM defconfig

  • 跨架构的 SoC 特定驱动程序,特别是用于 32 位和 64 位 ARM、RISC-V 和 Loongarch

这些“SoC 特定驱动程序”不包括时钟、GPIO 等具有其他顶级维护者的驱动程序。drivers/soc/ 目录通常用于内核内部的驱动程序,这些驱动程序被其他驱动程序用来提供 SoC 特定的功能,例如识别 SoC 版本或与电源域接口。

SoC 子系统还作为对 drivers/bus、drivers/firmware、drivers/reset 和 drivers/memory 的更改的中间位置。新平台的添加或现有平台的移除通常会通过 SoC 树,作为一个涵盖多个子系统的专用分支。

主 SoC 树位于 git.kernel.org 上

https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/

2.2. 维护者

很明显,这涉及相当广泛的主题,没有一个人,甚至一小群人能够维护。相反,SoC 子系统由许多子维护者(平台维护者)组成,他们各自负责维护单独的平台和驱动程序子目录。在这方面,“平台”通常指来自特定供应商的一系列 SoC,例如,英伟达的 Tegra SoC 系列。许多子维护者在供应商层面运作,负责多个产品线。由于多种原因,包括公司内部的收购/不同的业务部门,情况差异很大。各种子维护者都记录在 MAINTAINERS 文件中。

这些子维护者中的大多数都有他们自己的树,他们在其中暂存补丁,并向主 SoC 树发送拉取请求。这些树通常(但不总是)在 MAINTAINERS 中列出。

然而,SoC 树不是架构特定代码更改的位置。每个架构都有自己的维护者,负责架构细节、CPU 勘误表等。

2.2.1. 提交给定 SoC 的补丁

所有典型的平台相关补丁都应通过 SoC 子维护者(特定于平台的维护者)发送。这还包括对每个平台或共享 defconfig 的更改(在这种情况下,scripts/get_maintainer.pl 可能无法提供正确的地址)。

2.2.2. 向主 SoC 维护者提交补丁

只有在以下情况下,才能通过别名 soc@kernel.org 联系到主 SoC 维护者:

  1. 没有特定于平台的维护者。

  2. 特定于平台的维护者没有响应。

  3. 引入全新的 SoC 平台。此类新的 SoC 工作应首先发送到 scripts/get_maintainer.pl 指出的公共邮件列表,以供社区审查。在社区积极审查后,工作应以包含新的 arch/foo/Kconfig 条目、DTS 文件、MAINTAINERS 文件条目以及可选的初始驱动程序及其设备树绑定的一个补丁集的形式发送到 soc@kernel.org。MAINTAINERS 文件条目应列出新的特定于平台的维护者,他们将从现在开始负责处理该平台的补丁。

请注意,soc@kernel.org 通常不是讨论补丁的地方,因此发送到此地址的工作应被社区视为可接受的。

2.3. (新)子维护者的信息

随着新平台的涌现,它们通常会带来新的子维护者,其中许多人是为芯片供应商工作,可能不熟悉该流程。

2.3.1. 设备树 ABI 稳定性

也许最需要强调的事情之一是 dt-bindings 文档化了设备树和内核之间的 ABI。请阅读 设备树 (DT) ABI

如果对设备树进行的更改与旧内核不兼容,则在驱动程序完成或适当的时间之后,不应应用设备树补丁。最重要的是,任何不兼容的更改都应在补丁描述和拉取请求中明确指出,以及对现有用户(例如引导加载程序或其他操作系统)的预期影响。

2.3.2. 驱动程序分支依赖关系

一个常见的问题是同步设备驱动程序和设备树文件之间的更改。即使更改在两个方向上都兼容,这也可能需要协调如何通过不同的维护者树合并更改。

通常,包含驱动程序更改的分支也将包括对设备树绑定描述的相应更改,以确保它们实际上兼容。这意味着设备树分支最终可能会在“make dtbs_check”步骤中导致警告。如果设备树更改依赖于 include/dt-bindings/ 中头文件中缺少的添加,它将无法通过“make dtbs”步骤,也不会被合并。

有多种方法可以解决这个问题:

  • 避免在 include/dt-bindings/ 中为可以从数据手册导出的硬件常量定义自定义宏 —— 只有在没有自然的方法来定义绑定时,才应将头文件中的绑定宏作为最后手段。

  • 即使需要头文件,也在设备树文件中使用字面值来代替宏,并在后续版本中将其更改为命名表示。

  • 将设备树更改推迟到绑定和驱动程序已经合并之后的版本。

  • 在共享的不可变分支中更改绑定,该分支用作驱动程序更改和设备树更改的基础。

  • 在 #ifndef 部分的保护下,在设备树文件中添加重复定义,并在以后的版本中将其删除。

2.3.3. 设备树命名约定

设备树文件的通用命名方案如下。在 SoC 级别设置的平台的各个方面(如 CPU 内核)包含在名为 $soc.dtsi 的文件中,例如 jh7100.dtsi。集成细节(在板与板之间会有所不同)在 $soc-$board.dts 中描述。一个例子是 jh7100-beaglev-starlight.dts。通常,许多板是主题的变化,并且通常存在中间文件,例如 jh7100-common.dtsi,它位于 $soc.dtsi 和 $soc-$board.dts 文件之间,其中包含通用硬件的描述。

一些平台也有系统模块,其中包含一个 SoC,然后将其集成到几个不同的板中。对于这些平台,$soc-$som.dtsi 和 $soc-$som-$board.dts 是典型的。

目录通常以包含 SoC 时供应商的名称命名,这导致了树中的一些历史目录名称。

2.3.4. 验证设备树文件

make dtbs_check 可用于验证设备树文件是否符合描述 ABI 的 dt-bindings。请阅读 使用 json-schema 编写设备树绑定 的“运行检查”部分,以了解有关验证设备树的更多信息。

对于新平台或现有平台的添加,make dtbs_check 不应添加任何新的警告。对于 RISC-V 和三星 SoC,需要 make dtbs_check W=1 以不添加任何新的警告。如果对设备树的更改有任何疑问,请联系设备树维护者。

2.3.5. 分支和拉取请求

正如主 SoC 树有多个分支一样,预计子维护者也会这样做。驱动程序、defconfig 和设备树更改都应拆分为单独的分支,并以单独的拉取请求形式发送给 SoC 维护者。每个分支本身都应该可用,并避免因依赖其他分支而导致的回归。

也可以将少量补丁集以单独的电子邮件形式发送到 soc@kernel.org,并按相同的类别分组。

如果更改不符合正常模式,则可以有其他顶级分支,例如,用于树范围的重构,或添加包括 dts 文件和驱动程序的新 SoC 平台。

包含大量更改的分支可以受益于拆分为单独的主题分支,即使它们最终被合并到 SoC 树的同一分支中。这里的一个例子是,一个分支用于修复设备树警告,一个用于重构,一个用于新添加的板。

另一种常见的分支更改方法是在 rc1 和 rc4 之间的某个时间点发送一个早期拉取请求,其中包含大部分更改,然后在周期的末尾跟进一个或多个较小的拉取请求,这些请求可以添加晚期更改或解决在测试第一组时发现的问题。

虽然对晚期拉取请求没有截止时间,但随着时间越来越接近合并窗口,仅发送小分支会有所帮助。

针对当前版本的错误修复的拉取请求可以随时发送,但再次强调,多个较小的分支比试图将太多补丁合并到一个拉取请求中要好。

拉取请求的主题行应该以“[GIT PULL]”开头,并且使用签名标签而不是分支进行创建。该标签应包含一个简短的描述,总结拉取请求中的更改。有关发送拉取请求的更多详细信息,请参阅创建拉取请求