Pre-relocation device tree manipulation
1. Purpose
在某些市场中,嵌入式设备制造商提供某些系列的产品是有利的,其中一个系列中的设备的功能要么与另一个系列没有太大差异,要么可以被视为彼此的“扩展”, 其中一个设备与另一个设备的区别仅在于添加了少量功能(例如额外的输出连接器)。
要在硬件中实现这一点,一种方法是拥有一个主板以及可以连接到该主板的多个可能的子板。 不同的子板要么提供稍微不同的功能,要么将子板添加到设备中,实现对前面描述的设备的功能“扩展”。
对于软件,我们显然希望为设备的所有这些变体重复使用组件。 这意味着软件需要以某种方式应对某些 IC 可能出现也可能不出现在任何给定系统上的情况,具体取决于哪些子板连接到主板。
在Linux内核中,解决这个问题的一种可能的方法是采用设备树覆盖机制:存在一个“基础”设备树,它只包含保证存在于所有设备中的组件。 在内核启动时,会检测子板的存在和类型,并应用相应的设备树覆盖来支持子板上的组件。
请注意,当然,每种板上的组件都必须提供一种方法来查明是否安装了子板以及安装了哪些子板才能使该机制正常工作。
在 U-Boot 引导加载程序中,最近集成了对设备树覆盖的支持,并在某些主板上用于更改随后传递到 Linux 的设备树。 但由于 U-Boot 的驱动程序模型(也是基于设备树的)正在越来越多的驱动程序中使用,因此更改设备树的相同问题也开始出现在 U-Boot 本身中。
U-Boot 中设备树的另一个问题是它是只读的,并且当前的机制不允许在驱动程序模型初始化后轻松操作设备树。 虽然迁移到实时设备树(至少在重新定位之后)将大大简化此问题的解决方案,但实现它是一项不可忽视的任务,需要一个临时解决方案来至少在中期解决该问题。 学期。
因此,我们提出了通过提供特定于板的回调函数来解决此问题的方案,该回调函数将可写指针传递给设备树。 该函数在设备树重定位之前调用,特别是在主 U-Boot 的驱动程序模型实例化之前,因此主 U-Boot “看到”在此函数中对设备树所做的所有修改。 此外,我们现阶段拥有预重定位驱动程序模型,这意味着我们可以轻松查询硬件中组件的存在性和种类。
2. Implementation
为了利用预重定位设备树操作机制,板必须实现函数 board_fix_fdt,它具有以下签名:
int board_fix_fdt (void *rw_fdt_blob)
传入的 void 指针是指向设备树的可写指针,可用于使用例如操作设备树。 来自 include/fdt_support.h 的函数。 如果成功执行设备树操作,则返回值应为 0;如果失败,则返回值应为其他值。 请注意,从函数返回非空值将不可恢复地停止启动过程,就像 init_sequence_f 中的任何函数(在 common/board_f.c 中)一样。
此外,必须为要调用的函数设置 Kconfig 选项 OF_BOARD_FIXUP:
Device Tree Control
-> [*] Board-specific manipulation of Device Tree
警告:设备树的实际操作必须是 board_fix_fdt 中的最后一组操作! 由于预重定位驱动程序模型也不适应对设备树所做的更改,因此在对其进行操作后,其对设备树的引用将无效,并且在执行依赖于它们的函数时可能会出现不可预测的行为!
因此,board_fixup_fdt回调函数的推荐布局如下:
int board_fix_fdt(void *rw_fdt_blob)
{
/*
* Collect information about device's hardware and store
* them in e.g. local variables
*/
/* Do device tree manipulation using the values previously collected */
/* Return 0 on successful manipulation and non-zero otherwise */
}
如果保留此约定,则既可以采用“加法”方法,即将检测到的组件的节点添加到设备树中,也可以采用“减法”方法,即从树中删除缺少的组件的节点,以及 两种方法的结合应该有效。
3. Example
controlcenterdc 板 (board/gdsys/a38x/controlcenterdc.c) 具有 board_fix_fdt 功能,其中查询 I2C 总线上的 6 个 GPIO 扩展器(可能存在或不存在,因为它们位于子板上),然后将其停用 如果它们不存在,则在设备树中。
请注意,dm_i2c_simple_probe 函数不使用设备树,因此在操作树后调用它是安全的。
4. Work to be done
设备树覆盖的应用应该可以在board_fixup_fdt中实现,但现阶段尚未测试。