Linux内核之设备树插件DTO
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的工作流程:
- 编写设备树插件源文件,通过DTC工具编译生成.dtbo文件,存储在boot分区;
- 加载boot分区的设备树插件到内存;
- 在uboot中,合并设备树插件dtbo和设备树dtb文件为一个新的设备树,并得到内存指定地址;
- 启动内核,传递设备树在内存中的地址。
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加载
- uboot 中 DTO 启用:
CONFIG_CMD_DTIMG=y CONFIG_OF_LIBFDT_OVERLAY=y
- 然后将前面编译好的dtbo文件放到boot分区的对应目录,比如
/boot/dtb/overlay/
。 - 修改环境变量中的
dtoverlay
字段为指定的dtb文件,这里Uboot是从uEnv.txt中读取额外定义的环境变量列表,所以直接修改boot分区的/boot/uEnv/uEnv.txt
文件。 - 重启设备,系统就会加载我们新加的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 驱动!!!