想要测试未启用的开发板上的接口?或在设备树上执行小的更改,而无需定义完整的设备树,也不想修改原始设备树?或者,您可能希望将两线的串口更改为四根线,或者您需要启用或禁用不同模块型号上的功能?Digi Embedded Yocto 3.0 中的设备树覆盖机制使得通过小的更改修复原始设备树变得更加容易。
设备树是描述嵌入式系统上可用的硬件组件的数据结构。Linux 内核查询设备树,以找出在引导期间要加载的驱动程序。但是,复杂的嵌入式片上系统和工控主板可以启用不同的模块和功能组合,这需要多个设备树文件(blob)。
Digi Embedded Yocto 3.0 版本包含了用于处理设备树文件的新机制:设备树覆盖(device tree overlay)。设备树覆盖是特殊的设备树 blob 片段,允许你在启动操作系统之前动态覆盖设备树的特定部分。”blob”是设备树源文件的编译版本。这允许您将基本设备树与可选元素组合在一起,从而无需重新编译设备树便可以进行微小的更改。
自定义 Digi U-Boot dboot 命令加载基本设备树,并解析以逗号分隔的设备树覆盖文件名列表的内容,并按顺序加载每个覆盖层并将其应用于基本设备树。
本文介绍如何创建、生成和部署设备树覆盖以利用此机制。在文中,我们可以用简写的DT overlay来表示设备树覆盖(device tree overlay)。
设备树覆盖格式
设备树覆盖包含可应用于现有设备树 blob 的修改,其格式与典型的 *.dts 和 *.dtsi 文件略有不同:
DT overlay示例
#include <dt-bindings/gpio/gpio.h> /dts-v1/; /plugin/; / { fragment@0 { target-path = "/"; __overlay__ { foo { compatible = "custom,foo"; status = "okay"; gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>; }; }; }; fragment@1 { target = <&bar>; __overlay__ { my-boolean-property; status = "okay"; }; }; };
让我们一步一步解析上面的示例设备树覆盖文件,首先看到的是
* 设备树覆盖的标头:
#include <dt-bindings/gpio/gpio.h> /dts-v1/; /plugin/;
设备树覆盖是单独编译,并没有和想要覆盖的设备树文件有任何联系。因此它们需要像常规的设备树文件一样,包含标头文件和说明符。
* 根节点和片段:
/ { fragment@0 { [...] }; fragment@1 { [...] }; ... };
设备树覆盖必须具有根节点。在根节点中,必须插入片段:要修改的原始设备树的每个节点对应一个片段。
* 片段结构
分为绝对路径的片段和相对路径的片段
绝对路径片段:
fragment@0 { target-path = "/"; __overlay__ { foo { compatible = "custom,foo"; status = "okay"; gpio = <&gpio3 14 GPIO_ACTIVE_HIGH>; }; }; };
相对路径片段
fragment@1 { target = <&bar>; __overlay__ { my-boolean-property; status = "okay"; }; };
每个片段有两个元素:
- target:指向待修改片段的绝对路径或相对路径(带&号的节点别名)。
- _overlay_ 节点:内有需要应到到相关节点的修改内容。这些内容可以是:
- 新增的节点
- 新增的属性
- 现有的属性(用新值覆盖)
在上面的例子中,fragment@0是在根节点/上添加foo节点,而fragment@1 作用到别名为bar的节点,添加或是修改一些属性。
创建设备数覆盖(device tree overlay)
在Linux内核源码树中,原来存放有正常设备树的地方,创建一个设备树覆盖。ConnectCore 8系列是在arch/arm64/boot/dts/digi内。在这个例子中,DT overlay的文件名是custom_ov_foo_dts。Digi的设备树覆盖命名习惯,请参考File naming conventions。
编译设备树覆盖
为了让Linux内核编译设备树覆盖, 用扩展名.dtbo把它添加到arch/arm64/boot/dts/digi/Makefile中:
dtb-y += custom_ov_foo.dtbo
为了让DEY把DT overlay作为镜像的一部分发布,在项目的conf/local.conf中的KERNEL_DEVICETREE变量添加DT overlay文件名:
KERNEL_DEVICETREE += " custom_ov_foo.dtbo"
注意上面引号后留个空格。
部署设备树覆盖
有两种方式把设备树覆盖部署到目标板上:
- 把设备树文件拷贝到linux分区中
- 从UBoot中拷贝设备树到Linux分区
- 在Linux下拷贝设备树到Linux分区
可以用tftp或是sd卡等方式:
=> updatefile linux tftp custom_ov_foo.dtbo
您需要以可读写的方式重新加载Linux分区
~# mount -o remount,rw /mnt/linux
然后拷贝文件到该分区上。
- 把带有该设备树的linux分区固件刷到目标板上
请参考固件升级的操作文档。
启用设备树覆盖
1. 在U-Boot中添加overlay变量,如果有多个DT overlay,文件名以逗号隔开。
=> env edit overlays edit: custom_ov_foo.dtbo
2. 重启或是直接用dboot命令从flash启动
=> dboot linux mmc