博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设备树中ranges属性分析(1)
阅读量:6947 次
发布时间:2019-06-27

本文共 6630 字,大约阅读时间需要 22 分钟。

作者

彭东林
pengdonglin137@163.com
 

软件环境

Linux-4.10.17
Qemu+vexpress
 

概述

在设备树中有时会看到ranges属性,这个ranges属性可以达到什么效果呢? 今天看到,才知道。为了有一个直观的印象,下面我们结合一个实际的例子来看看
 

正文

一、设备树

下面是我们将要实验的设备树的例子:
1 / {  2     #address-cells = <1>;  3     #size-cells = <1>;  4   5     demo_level0 {  6         compatible = "simple-bus";  7         ranges = <0x0 0x3000000 0x3000>;  8         #address-cells = <1>;  9         #size-cells = <1>; 10  11         range@0 { 12             compatible = "range"; 13             reg = <0x100 0x200>; 14             reg-names = "range0"; 15         }; 16  17         range@1 { 18             compatible = "range"; 19             reg = <0x300 0x200>; 20             reg-names = "range1"; 21         }; 22  23         range@2 { 24             compatible = "range"; 25             reg = <0x600 0x200>; 26             reg-names = "range2"; 27         }; 28  29         demo_level1 { 30             compatible = "simple-bus"; 31             ranges = <0x0 0x1000 0x1000>; 32             #address-cells = <1>; 33             #size-cells = <1>; 34  35             range@3 { 36                 compatible = "range"; 37                 reg = <0x100 0x200>; 38                 reg-names = "range3"; 39             }; 40  41             demo_level1-1 { 42                 compatible = "simple-bus"; 43                 ranges = <0x0 0x300 0x500>; 44                 #address-cells = <1>; 45                 #size-cells = <1>; 46  47                 range@4 { 48                     compatible = "range"; 49                     reg = <0x100 0x200>; 50                     reg-names = "range4"; 51                 }; 52  53                 range@5 { 54                     compatible = "range"; 55                     reg = <0x300 0x100>; 56                     reg-names = "range5"; 57                 }; 58  59                 demo_level1-1-1 { 60                     compatible = "simple-bus"; 61                     ranges = <0x0 0x400 0x100>; 62                     #address-cells = <1>; 63                     #size-cells = <1>; 64  65                     range@6 { 66                         compatible = "range"; 67                         reg = <0x50 0x30>; 68                         reg-names = "range6"; 69                     }; 70  71                     demo_level1-1-1-1 { 72                         compatible = "simple-bus"; 73                         ranges = <0x0 0x20 0x20>; 74                         #address-cells = <1>; 75                         #size-cells = <1>; 76  77                         range@7 { 78                             compatible = "range"; 79                             reg = <0x10 0x10>; 80                             reg-names = "range7"; 81                         }; 82  83                         range@8 { 84                             compatible = "range"; 85                             reg = <0x0 0x10>; 86                             reg-names = "range8"; 87                         }; 88                     }; 89                 }; 90             }; 91  92             range@9 { 93                 compatible = "range"; 94                 reg = <0x800 0x50>; 95                 reg-names = "range9"; 96             }; 97  98             demo_level1-2 { 99                 compatible = "simple-bus";100                 ranges = <0x0 0x900 0x100>;101                 #address-cells = <1>;102                 #size-cells = <1>;103 104                 range@10 {105                     compatible = "range";106                     reg = <0x0 0x50>;107                     reg-names = "range10";108                 };109 110                 demo_level1-2-1 {111                     compatible = "simple-bus";112                     ranges;113                     #address-cells = <1>;114                     #size-cells = <1>;115 116                     range@11 {117                         compatible = "range";118                         reg = <0x50 0x30>;119                         reg-names = "range11";120                     };121                 };122             };123         };124 125         demo_level2 {126             compatible = "simple-bus";127             ranges;128             #address-cells = <1>;129             #size-cells = <1>;130 131             range@12 {132                 compatible = "range";133                 reg = <0x2000 0x1000>;134                 reg-names = "range12";135             };136         };137     }138 };
 

二、驱动

下面是一个简单的驱动,功能很简单,只是在probe函数中将memory资源的start和(end+1)打印出来.
demo_range.c:
#include 
#include
#include
#include
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)打印出来,之所以这里用(end+1),仅仅是为了便于理解下面的kernel log。

三、验证

编译驱动,然后加载,可以看到下面的打印信息:
[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理解下面的框图
 
 
 
 
完。

转载地址:http://zghnl.baihongyu.com/

你可能感兴趣的文章
是运维就必须硬起来,插件化运维系统思路
查看>>
ibatis bug
查看>>
L7 linux shell编程练习
查看>>
开会 顺口溜
查看>>
用PHP和树莓派开发一个比特币/以太坊交易机器人
查看>>
有热备,有事物损坏 薛忠权(ERIKXUE)
查看>>
MySQL入门(二)
查看>>
手把手教 centos+nginx1.3.9+php5.4.9+mysql5.5.28+memcached
查看>>
PHP设计模式(3)观察者模式
查看>>
数据库中的左连接(left join)和右连接(right join)区别
查看>>
spring data jpa 调用oracle 存储过程
查看>>
夺命雷公狗---无限极分类NO4
查看>>
Teams新功能更新【已发布】Teams PowerShell 命令详解
查看>>
我的友情链接
查看>>
Ansible快速开始-指挥集群
查看>>
Java容器详解(以Array Arrays ArrayList为例)
查看>>
Iterator和ListIterator迭代器
查看>>
思科默认 NAT timeout
查看>>
error 1067 (42000) at line 1:Invalid default value for 'id'
查看>>
我的友情链接
查看>>