赞
踩
硬件:韦东山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__ { /*在此添加要插入的节点*/ }; }; };
/dts-v1/
:指定 dts 版本;/plugin/
:表示设备树插件中可以引用设备树中的节点。因为这些节点在设备树插件中是未定义的,要加上/plugin/才可使用;/
节点,然后需要覆盖的地方用fragment@x
作为节点名称:
target-path = "/can@0x0"
:为需要覆盖的节点路径;__overlay__
:我们要插入的设备及节点或者要引用(追加)的设备树节点放在__overlay__{}
内。例如现在要利用设备树插件将can0禁用。
1、查看原始设备树board.dts,确定can0的节点路径:
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.dtbkernel-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
设备树覆盖前的CAN功能是正常的:
【以下命令均在uboot命令行执行】
0x44851e58
切换到了0x44831e58
,实际就是从uboot设备树切换到了kernel设备树:fdt addr 0x44831e58
fatload mmc 2:1 0x43000000 kerneldtbo/kernel-overlay-can.dtb
fdt resize 8192
0x43000000
处的设备树插件覆盖到工作设备树:fdt apply 0x43000000
boot
此时CAN测试会提示找不到CAN端口,说明设备树插件覆盖成功:
1、设备树插件里所要修改的节点,一定要在工作设备树中存在,否则fat apply时会提示FDT_ERR_NOTFOUND
错误:
2、关于设备树插件加载到指定地址的这个“地址”是如何确定的,下面解释一下,但不严谨:
在内核cmdline加上memblock=debug
、bootmem_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
...
...
可以发现0x4210ffff
到0x448df000
中间有一段空出的空间,所以取了0x43000000
。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。