设备树插件dtbo介绍与应用

环境介绍

硬件:韦东山T113工控板
软件:Tina5.0 SDK

设备树插件简介

什么是设备插件

设备树插件DTBO(Device Tree Blob Overlay)是一种用于Linux内核和嵌入式系统的重要机制,主要用于动态地修改或扩展系统运行时的设备树配置。

为什么要用设备树插件

使用设备树插件的话,可以根据具体的外设来定制设备树插件,做到灵活替换。比如一个单板需要适配多种不同型号的屏幕,可以提前为每个屏幕做好一个设备树插件,用到哪个屏就动态替换对应的设备树插件。而不用换屏幕时,又去修改原始设备树文件,这样又得重新编译,重新烧录。

如何生成设备树插件

设备树插件语法

/dts-v1/;
/plugin/;

 / {
    fragment@0 {
        target-path = "/can@0x0";
        __overlay__ {
            /*在此添加要插入的节点*/
        };
    };

    fragment@1 {
        target-path = "/can@0x1";
        __overlay__ {
            /*在此添加要插入的节点*/
        };
    };
 };
  • 头部是作为一个 overlay 的描述:
    • /dts-v1/:指定 dts 版本;
    • /plugin/:表示设备树插件中可以引用设备树中的节点。因为这些节点在设备树插件中是未定义的,要加上/plugin/才可使用;
  • 然后有个/节点,然后需要覆盖的地方用fragment@x作为节点名称:
    • target-path = "/can@0x0":为需要覆盖的节点路径;
    • __overlay__:我们要插入的设备及节点或者要引用(追加)的设备树节点放在__overlay__{}内。

设备树插件语法举例

例如现在要利用设备树插件将can0禁用。
1、查看原始设备树board.dts,确定can0的节点路径:
image.png
2、可以发现,can0节点是直接挂在根节点下的,所以插件中要覆盖的节点路径就为/+ can@0x0

/dts-v1/;
/plugin/;

 / {
    fragment@0 {
        target-path = "/can@0x0";	//需要覆盖的节点路径
        __overlay__ {
            /*在此添加要插入的节点*/
        };
    };
 };

3、在__overlay__中按需加入或修改设备的属性,此例要将can0禁用,所以设置status为disabled:

/dts-v1/;
/plugin/;

 / {
    fragment@0 {
        target-path = "/can@0x0";		//需要覆盖的节点路径
        __overlay__ {
            #address-cells = <1>;
    		#size-cells = <0>;
    		compatible = "allwinner,sun8i-can";
    		device_type = "can0";
    		id = <0>;
    		status = "disabled";	//禁用can0
        };
    };
};

4、若也要禁用can1,可再加一个fragment@1节点:

/dts-v1/;
/plugin/;

 / {
    fragment@0 {
        target-path = "/can@0x0";		//需要覆盖的节点路径
        __overlay__ {
            #address-cells = <1>;
    		#size-cells = <0>;
    		compatible = "allwinner,sun8i-can";
    		device_type = "can0";
    		id = <0>;
    		status = "disabled";		//禁用can0
        };
    };

    fragment@1 {
        target-path = "/can@0x1";		//需要覆盖的节点路径
        __overlay__ {
            #address-cells = <1>;
    		#size-cells = <0>;
    		compatible = "allwinner,sun8i-can";
    		device_type = "can1";
    		id = <0>;
    		status = "disabled";		//禁用can1
        };
    };
     
 };

编译设备树插件

dtc -I dts -O dtbo -o kernel-overlay-can.dtbo kernel-overlay-can.dts
  • dtc:这是 Device Tree Compiler 的命令行工具
  • -I dts:指定输入文件的格式为 dts(Device Tree Source)
  • -O dtb:指定输出文件的格式为 dtb(Device Tree Blob)
  • -o kernel-overlay-can.dtb:指定输出文件的名称为 kernel-overlay-can.dtb
  • kernel-overlay-can.dts:输入文件的名称

常见的编译命令都是上面这样,但使用上面命令会报设备树语法错误,不知道是不是dtc编译器的问题。使用下面命令可以正常编译:

<sdk>/out/t113/kernel/build/scripts/dtc/dtc -I dts -O dtb -o kernel-overlay-can.dtb kernel-overlay-can.dts
  • <sdk>/.../dtc:使用tina sdk内核里的dtc
  • -O dtb:这里的指定的输出类型是dtb而不是dtbo
  • -o kernel-overlay-can.dtb:输出文件的后缀也是dtb

至此,设备树插件编译成功。

设备树插件应用

内核配置

配置CONFIG_OF_OVERLAY = y

Device Drivers 
    -> Device Tree and Open Firmware support 
        -> [*]Device Tree overlays

image.png

应用

设备树覆盖前的CAN功能是正常的:
image.png

设置工作设备树地址

【以下命令均在uboot命令行执行】

  • 可以通过uboot启动信息,查看设备树地址。下面红框内容表明,工作设备树从0x44851e58切换到了0x44831e58,实际就是从uboot设备树切换到了kernel设备树:

image.png

  • 设置工作设备树为kernel设备树,也可以不设置,因为此时已切换到了kernel设备树:
fdt addr 0x44831e58

加载设备树插件到内存

  • 从emmc的boot-resource分区的kerneldtbo文件夹加载设备树插件到内存(据实际情况自行加载,在本文最后会简单介绍一下内存地址如何确定):
fatload mmc 2:1 0x43000000 kerneldtbo/kernel-overlay-can.dtb
fdt resize 8192

设备树覆盖

  • 将内存0x43000000处的设备树插件覆盖到工作设备树:
fdt apply 0x43000000

启动

boot

验证

此时CAN测试会提示找不到CAN端口,说明设备树插件覆盖成功:
image.png

总结

问题

1、设备树插件里所要修改的节点,一定要在工作设备树中存在,否则fat apply时会提示FDT_ERR_NOTFOUND错误:
image.png
2、关于设备树插件加载到指定地址的这个“地址”是如何确定的,下面解释一下,但不严谨:
在内核cmdline加上memblock=debugbootmem_debug=1两个参数,在内核启动时,会打印reserved memory详细信息。
重启开发板,会有如下类似的提示信息:

Starting kernel ...
...
...
memblock_reserve: [0x40100000-0x40eabcef] arm_memblock_init+0x20/0x78
memblock_reserve: [0x40004000-0x40007fff] arm_memblock_init+0x24/0x78
memblock_reserve: [0x41800000-0x4181ffff] arm_memblock_init+0x38/0x78
memblock_reserve: [0x41900000-0x41ffffff] early_init_fdt_scan_reserved_mem+0x64/0xa0
memblock_reserve: [0x42000000-0x420fffff] early_init_fdt_scan_reserved_mem+0x64/0xa0
memblock_reserve: [0x42100000-0x4210ffff] early_init_fdt_scan_reserved_mem+0x64/0xa0
memblock_reserve: [0x448df000-0x44cc6fff] early_init_fdt_scan_reserved_mem+0x64/0xa0
memblock_reserve: [0x47000000-0x47ffffff] memblock_alloc_range_nid+0xb0/0x128
...
...

可以发现0x4210ffff0x448df000中间有一段空出的空间,所以取了0x43000000

参考文章

聊聊SOC启动(八) uboot启动流程三
覆盖设备树(Devices-tree overlays)

  • 12
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值