系统对 Device Tree Overlays 的支持方式

2020-05-22 16:03:27来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

系统对 Device Tree Overlays 的支持方式

Device Tree Overlays、 dtbo、设备树堆叠功能

问题来源:

野火 iMX 6ULL 开发板资料。
https://tutorial.linux.doc.embedfire.com/zh_CN/latest/linux_basis/fire-config_brief.html

5.3. fire-config机制

一般而言,fire-config旨在提供一些常见的系统功能配置服务,在进行配置过程中, 这可能会导致/boot/uEnv.txt或者是其他各种标准的linux配置文件被自动更改了, 某些选项需要重启才能生效,如果您修改了其中一个,fire-config 会在<Finish> 按钮被选择时,询问您是否要立即重启,如果您希望配置马上生效,确定重启系统即可。  

5.4. Device Tree Overlays

fire-config工具集成了Device Tree Overlays机制,用来管理一些硬件资源的分配和模块的加载, 从而缓解多个驱动程序争用系统资源的问题。

在传统开发模式中,这个机制通常是由设备树来完成的:在开发之前根据项目需求, 提前确定系统中所有用到的硬件设备。在设备树中把所有的外围设备信息以设备树特定的语法进行描述, 在设备树被编译为dtb文件后,被linux内核加载使用。

可以看到,在传统开发过程,一旦硬件资源发生变化,就要重新修改、编译、下载设备树。比较极端的情况是: 当项目中要支持多种的硬件模块,而不同模块间往往会共用某些系统资源(如IO引脚)。 一旦系统要兼容模块任意组合使用,那么随着模块数量增加,需要编译的设备树数量将爆炸增长。

因此,使用传统设备树是不利于项目的维护和扩展的。内核为了解决这个提出了一套新的解决方案, 那就是Device Tree Overlays,中文上可理解为”设备树插件”。 它的核心原理是,通过扩展传统的设备树语法,使得各个硬件模块的信息可以独立地用新的设备树语法来描述。 这样一来,传统的主设备树中只需要保留最基础的硬件信息(主要是cpu和内存),其他模块单独编译成”设备树插件”。 在系统实际使用时,根据实际应用情景,需要用到哪些硬件模块就把对应的设备树插件加入到主设备树即可。

“设备树插件”无疑提高了系统的可维护性和减少了大量的重复工作,目前, 我们已经把常见的硬件模块都编译成了”设备树插件”,比如LCD、HDMI、WiFi等等。 用户可以通过fire-config工具轻松地实现对硬件模块的便捷管理。

原本问题:

5.3 节 最后一句: 如果您希望配置马上生效,确定重启系统即可。

既然是“插件”,为什么要重启? 不是热拔插的么?

究竟在哪里加载 overlay 文件进内核的?

  1. 内核加载的?
  2. 操作系统加载的?

Device Tree Overlays 是怎么运行的?

有朋友问我 Device Tree Overlays 是什么,怎么没听说过。确实百度很少找到资料。 
我给出的中文名叫 设备树堆叠功能。不一定准确。
内核描述在 Documentation/devicetree/overlay-notes.txt 

Device Tree Overlays 核心定义:

在 kernel 启动以后系统加载时候修改或者增加部分dts,最终把整个系统需要的设备驱动全部加载进去。

用处:

动态修改设备树。
在用户空间配置内核对象 Device Tree。

本质:

configfs - Userspace-driven kernel object configuration. 直接翻译过来就是用户空间配置内核对象,在configfs.txt中可以看到其中的描述:configfs是一个基于ram的文件系统,通过对该文件系统的操作实现对内核对象的配置。
uboot 启动内核

从 <Device Tree Overlays 核心定义> 来看,不是uboot的操作。
bootm <uImage_addr> <initrd_addr> <dtb_addr>

内核对 dtb 文件的解析位置

start_kernel -->setup_arch(&command_line) -->setup_machine_fdt(__fdt_pointer) -->unflatten_device_tree()

overlays 的调用位置
  1. drivers/of/overlay.c 核心代码。
    // Create and apply an overlay
    int of_overlay_create(struct device_node *tree);
    // Removes an overlay
    int of_overlay_destroy(int id);
    // Removes all overlays from the system
    int of_overlay_destroy_all(void);

  2. 查找到 of_overlay_create 被 drivers/of/configfs.c 使用。
    configfs.c 最后一行 late_initcall(of_cfs_init) 标记 of_cfs_init 加入到 内核 .init 段。

  3. .init 段被调用位置
    start_kernel -->rest_init() -->kernel_init() --> kernel_init_freeable() -->do_basic_setup() -->do_initcalls()
    注意: kernel_init_freeable() 是 kernel_init() 第一行。
    kernel_init 在完成一系列初始化之后启动第一个用户进程。内核启动过程就结束了。

  4. 调用 of_cfs_init 会在 /sys/kernel/config/ 目录下创建 /sys/kernel/config/device-tree/overlay 文件(内存文件系统)。

configfs.c 的具体分析见参考文章
https://blog.csdn.net/liujiliei/article/details/105276551

内核启动流程。

void __init start_kernel(void)
{
....
setup_arch(&command_line);
....
rest_init();
}

结论

/boot/overlay 目录下的 *.dtbo 文件并不是内核启动过程中加载和处理的。

那么就要看是不是 UBOOT 和 操作系统init进程做的了。 稍后进行。

友善Nanopi neo core2

在该产品/boot 目录下发现 overlay 相关内容。
分析 npi-config 使用的是 fdtput fdtget fdtdump 直接操作 /boot/.dtb 文件。
并没有使用到 /boot/overlay/
目录下的 *.dtbo (overlay文件)文件。

参考文章:

https://blog.csdn.net/u014135607/article/details/79949571
https://blog.csdn.net/liujiliei/article/details/105276551

http://tinylab.org/lwn-616859/

国内论坛对此描述很少(某度也很不给力),本人英文很差。资源获取很曲折,浪费不少时间。 大概整理的就这么多。


原文链接:https://www.cnblogs.com/JiuHuan/p/12940074.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:VMware如何克隆一个虚拟机

下一篇:Linux命令(12)pwd命令