设备树dts中的ranges作用
一、设备树
下面是我们将要实验的设备树的例子:
/ { #address-cells = <1>; #size-cells = <1>; demo_level0 { compatible = "simple-bus"; ranges = <0x0 0x3000000 0x3000>; #address-cells = <1>; #size-cells = <1>; range@0 { compatible = "range"; reg = <0x100 0x200>; reg-names = "range0"; }; range@1 { compatible = "range"; reg = <0x300 0x200>; reg-names = "range1"; }; range@2 { compatible = "range"; reg = <0x600 0x200>; reg-names = "range2"; }; demo_level1 { compatible = "simple-bus"; ranges = <0x0 0x1000 0x1000>; #address-cells = <1>; #size-cells = <1>; range@3 { compatible = "range"; reg = <0x100 0x200>; reg-names = "range3"; }; demo_level1-1 { compatible = "simple-bus"; ranges = <0x0 0x300 0x500>; #address-cells = <1>; #size-cells = <1>; range@4 { compatible = "range"; reg = <0x100 0x200>; reg-names = "range4"; }; range@5 { compatible = "range"; reg = <0x300 0x100>; reg-names = "range5"; }; demo_level1-1-1 { compatible = "simple-bus"; ranges = <0x0 0x400 0x100>; #address-cells = <1>; #size-cells = <1>; range@6 { compatible = "range"; reg = <0x50 0x30>; reg-names = "range6"; }; demo_level1-1-1-1 { compatible = "simple-bus"; ranges = <0x0 0x20 0x20>; #address-cells = <1>; #size-cells = <1>; range@7 { compatible = "range"; reg = <0x10 0x10>; reg-names = "range7"; }; range@8 { compatible = "range"; reg = <0x0 0x10>; reg-names = "range8"; }; }; }; }; range@9 { compatible = "range"; reg = <0x800 0x50>; reg-names = "range9"; }; demo_level1-2 { compatible = "simple-bus"; ranges = <0x0 0x900 0x100>; #address-cells = <1>; #size-cells = <1>; range@10 { compatible = "range"; reg = <0x0 0x50>; reg-names = "range10"; }; demo_level1-2-1 { compatible = "simple-bus"; ranges; #address-cells = <1>; #size-cells = <1>; range@11 { compatible = "range"; reg = <0x50 0x30>; reg-names = "range11"; }; }; }; }; demo_level2 { compatible = "simple-bus"; ranges; #address-cells = <1>; #size-cells = <1>; range@12 { compatible = "range"; reg = <0x2000 0x1000>; reg-names = "range12"; }; }; } };
二、驱动
下面是一个简单的驱动,功能很简单,只是在probe函数中将memory资源的start和(end+1)打印出来.
demo_range.c:
#include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of.h> static int demo_range_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); printk(KERN_INFO "%s start: 0x%x, end: 0x%x\n", res->name, res->start, res->end + 1); return 0; } static int demo_range_remove(struct platform_device *pdev) { return 0; } static const struct of_device_id demo_range_of_match[] = { { .compatible = "range"}, {}, }; static struct platform_driver demo_range_driver = { .driver = { .name = "demo_range", .owner = THIS_MODULE, .of_match_table = demo_range_of_match, }, .probe = demo_range_probe, .remove = demo_range_remove, }; module_platform_driver(demo_range_driver); MODULE_LICENSE("GPL v2");
在驱动中会获得memory资源,然后将start和(end+1)打印出来。
三、验证
编译驱动,然后加载,可以看到下面的打印信息:
[root@vexpress mnt]# insmod demo_range.ko [ 382.940402] range0 start: 0x3000100, end: 0x3000300 [ 382.940697] range1 start: 0x3000300, end: 0x3000500 [ 382.941448] range2 start: 0x3000600, end: 0x3000800 [ 382.941657] range3 start: 0x3001100, end: 0x3001300 [ 382.941855] range4 start: 0x3001400, end: 0x3001600 [ 382.942057] range5 start: 0x3001600, end: 0x3001700 [ 382.942262] range6 start: 0x3001750, end: 0x3001780 [ 382.942470] range7 start: 0x3001730, end: 0x3001740 [ 382.942684] range8 start: 0x3001720, end: 0x3001730 [ 382.949796] range9 start: 0x3001800, end: 0x3001850 [ 382.950023] range10 start: 0x3001900, end: 0x3001950 [ 382.950603] range11 start: 0x3001950, end: 0x3001980 [ 382.950805] range12 start: 0x3002000, end: 0x3003000
总结:
1、ranges属性值的格式 <local地址, parent地址, size>, 表示将local地址向parent地址的转换。
比如对于#address-cells和#size-cells都为1的话,以<0x0 0x10 0x20>为例,表示将local的从0x0~(0x0 + 0x20)的地址空间映射到parent的0x10~(0x10 + 0x20)
其中,local地址的个数取决于当前含有ranges属性的节点的#address-cells属性的值,size取决于当前含有ranges属性的节点的#size-cells属性的值。
而parent地址的个数取决于当前含有ranges属性的节点的parent节点的#address-cells的值。
2、对于含有ranges属性的节点的子节点来说,其reg都是基于local地址的
3、ranges属性值为空的话,表示1:1映射
4、对于没有ranges属性的节点,代表不是memory map区域
四、示意图
对照上面的log理解下面的框图