Linux内核之设备树插件DTO

什么是DTO(Device Tree Overlay)

Linux4.4以后引入了动态设备树(Dynamic DeviceTree),我们这里翻译为“设备树插件”,或者称“设备树叠加层”。
设备树插件(Device Tree Overlay,叠加层)是一种用于设备树(Device Tree)的扩展机制,可以理解为主设备树的“补丁”它动态的加载到系统中,无需重新编译整个设备树。
它允许在运行时动态修改设备树的内容,以便添加、修改或删除设备节点和属性,这样就提供了一种灵活的方式来配置和管理硬件设备,而无需重新编译整个设备树。

几个概念

  • FDT: Flattened Device Tree

  • DTS: Devicetree Sources,是用于描述 FDT(设备树) 的源文件

  • DTO: Devcie Tree Overlay,设备树插件(或者说叠加层)

  • DTC: Device Tree Compiler,顾名思义,是FDT(设备树) 的编译器

  • DTB: Device Tree Blob,DTS经过DTC编译后而生成

  • DTBO: Device Tree Blob for Overlay,设备树插件(或者说叠加层)经过DTC编译后而生成

DTO工作流程

以下是uboot中加载DTO的工作流程:

  1. 编写设备树插件源文件,通过DTC工具编译生成.dtbo文件,存储在boot分区;
  2. 加载boot分区的设备树插件到内存;
  3. 在uboot中,合并设备树插件dtbo和设备树dtb文件为一个新的设备树,并得到内存指定地址;
  4. 启动内核,传递设备树在内存中的地址。

DTO语法格式

设备树插件(DTO)是在设备树基础上增加的内容,与设备树语法基本一样, 甚至我们可以直接将之前编写的设备树节点复制到DTO里。
设备树插件拥有相对固定的格式,甚至可以认为它只是把设备节点加了一个“壳”编译后内核能够动态加载它。

格式一

/dts-v1/;
/plugin/;

 / {
        fragment@0 {
            target-path = "/";
            /*固定写法 */
            __overlay__ {
                /*在此添加要插入的节点*/
                .......
            };
        };

        /*固定写法fragment@x */
        fragment@1 {
            /*从根结点的开始的绝对路径 */
            target = <&XXXXX>;
            __overlay__ {
                /*在此添加要插入的节点*/
                .......
            };
        };
    .......
 };

格式二

/dts-v1/;
/plugin/;

&{/} {
    /*此处在根节点"/"下,添加要插入的节点或者属性*/
};

/*使用节点的别名 */
&XXXXX {
    /*此处在节点"XXXXX"下,添加要插入的节点或者属性*/
};

编译

和设备树文件 dts 是一样的,dto也是用 dtc 编译器编译,可以在内核源码中直接编译,或者使用DTC单独编译:

#将 dtbo 反编译成 dts 
dtc -I dts -O dtb overlay.dts -o overlay.dtbo
#将 dtbo 反编译成 dts 
dtc -I dtb -O dts overlay.dtbo -o overlay.dts

使用

uboot加载

  1. uboot 中 DTO 启用:
    CONFIG_CMD_DTIMG=y
    CONFIG_OF_LIBFDT_OVERLAY=y
  2. 然后将前面编译好的dtbo文件放到boot分区的对应目录,比如/boot/dtb/overlay/
  3. 修改环境变量中的dtoverlay字段为指定的dtb文件,这里Uboot是从uEnv.txt中读取额外定义的环境变量列表,所以直接修改boot分区的/boot/uEnv/uEnv.txt文件。
  4. 重启设备,系统就会加载我们新加的dtbo。

通过sysfs动态加载

进入/sys/kernel/config/device-tree/overlays/,新建一个文件夹,将dtbo文件复制进去,然后echo 1 > status即可。即:

cd /sys/kernel/config/device-tree/overlays/
mkdir xxx && cd xxx
#创建xxx后,在该文件夹里面会自动生成两个文件 dtbo 和 status
#然后将 overlay.dtbo 文件内容写入到 dtbo 里
cat xxx.dtbo > dtbo
#使能 dtbo
echo 1 > status

#删除dto
rmdir /sys/kernel/config/device-tree/overlays/xxx

注意: 以上操作的前提是内核已加载 dtbocfg 驱动!!!

参考