作者

彭东林
pengdonglin137@163.com
 

软件环境

Linux-4.10.17
Qemu+vexpress
 

概述

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

正文

一、设备树

下面是我们将要实验的设备树的例子:
 / {
#address-cells = <>;
#size-cells = <>; demo_level0 {
compatible = "simple-bus";
ranges = <0x0 0x3000000 0x3000>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x100 0x200>;
reg-names = "range0";
}; range@ {
compatible = "range";
reg = <0x300 0x200>;
reg-names = "range1";
}; range@ {
compatible = "range";
reg = <0x600 0x200>;
reg-names = "range2";
}; demo_level1 {
compatible = "simple-bus";
ranges = <0x0 0x1000 0x1000>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x100 0x200>;
reg-names = "range3";
}; demo_level1- {
compatible = "simple-bus";
ranges = <0x0 0x300 0x500>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x100 0x200>;
reg-names = "range4";
}; range@ {
compatible = "range";
reg = <0x300 0x100>;
reg-names = "range5";
}; demo_level1-- {
compatible = "simple-bus";
ranges = <0x0 0x400 0x100>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x50 0x30>;
reg-names = "range6";
}; demo_level1--- {
compatible = "simple-bus";
ranges = <0x0 0x20 0x20>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x10 0x10>;
reg-names = "range7";
}; range@ {
compatible = "range";
reg = <0x0 0x10>;
reg-names = "range8";
};
};
};
}; range@ {
compatible = "range";
reg = <0x800 0x50>;
reg-names = "range9";
}; demo_level1- {
compatible = "simple-bus";
ranges = <0x0 0x900 0x100>;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x0 0x50>;
reg-names = "range10";
}; demo_level1-- {
compatible = "simple-bus";
ranges;
#address-cells = <>;
#size-cells = <>; range@ {
compatible = "range";
reg = <0x50 0x30>;
reg-names = "range11";
};
};
};
}; demo_level2 {
compatible = "simple-bus";
ranges;
#address-cells = <>;
#size-cells = <>; range@ {
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, ); printk(KERN_INFO "%s start: 0x%x, end: 0x%x\n",
res->name, res->start, res->end + ); return ;
} static int demo_range_remove(struct platform_device *pdev)
{
return ;
} 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理解下面的框图
 

 
 
 
完。

设备树中ranges属性分析(1)的更多相关文章

  1. of_alias_get_id 函数与设备树中aliases节点的关系【转】

    转自:https://blog.csdn.net/qq_30145093/article/details/78053823?locationNum=10&fps=1 转自http://www. ...

  2. 我眼中的Linux设备树(三 属性)

    三 属性(property)device_type = "memory"就是一个属性,等号前边是属性,后边是值.节点是一个逻辑上相对独立的实体,属性是用来描述节点特性的,根据需要一 ...

  3. Linux设备树(三 属性)

    三 属性(property) device_type = "memory"就是一个属性,等号前边是属性,后边是值.节点是一个逻辑上相对独立的实体,属性是用来描述节点特性的,根据需要 ...

  4. xx系统属性分析

    在本周的课程学习当中,我们简单了解到系统的一些属性,同时在课下也对<大型网站技术架构:核心原理与案例分析>进行了初步的阅读. 在书籍中我看到了许多其他的知识,也对课堂学习的知识有了巩固,现 ...

  5. 设备树中的interrupts属性解析

    interrupts属性会有两种不同的参数: 1. 带两个参数的情形 示例:  interrupt-parent = <&gpio2>; interrupts = <5 1& ...

  6. OpenStack_Swift源代码分析——创建Ring及加入�设备源代码算法具体分析

    1 创建Ring 代码具体分析 在OpenStack_Swift--Ring组织架构中我们具体分析了Ring的具体工作过程,以下就Ring中添加�设备,删除设备,已经又一次平衡的实现过程作具体的介绍. ...

  7. Android中<uses-sdk>属性和target属性分析

    1. 概要 <uses-sdk> 用来描述该应用程序可以运行的最小和最大API级别,以及应用程序开发者设计期望运行的平台版本.通过在manifest清单文件中添加该属性,我们可以更好的控制 ...

  8. iOS获取用户设备崩溃日志并分析

    项目最近发布,部分用户在内侧使用,正好遇到一些问题,由于用户在其他城市,所以对于用户设备产生的崩溃日志,不好直接拿设备连接电脑. 对于这种情况,我们可以这样: 1.引导用户开启iOS设备设置-> ...

  9. Linux块设备加密之dm-crypt分析

    相关的分析工作一年前就做完了,一直懒得写下来.现在觉得还是写下来,以来怕自己忘记了,二来可以给大家分享一下自己的研究经验. 这篇文章算是<Device Mapper代码分析>的后续篇,因为 ...

随机推荐

  1. 每天一个linux命令:scp命令

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  2. ubuntu 电源管理

    https://www.cnblogs.com/sky-heaven/p/4561374.html?tdsourcetag=s_pcqq_aiomsg  挂起命令 echo mem > /sys ...

  3. bzoj1036点权模板题

    /* HYSBZ1036 树上有1-n个结点,每个节点都有一个权值w 操作 CHANGE u t:把结点u的权值改为t QMAX u v:询问从点u到v的路径上的节点的最大权值 QSUM u v:询问 ...

  4. python 全栈开发,Day32(知识回顾,网络编程基础)

    一.知识回顾 正则模块 正则表达式 元字符 : . 匹配除了回车以外的所有字符 \w 数字字母下划线 \d 数字 \n \s \t 回车 空格 和 tab ^ 必须出现在一个正则表达式的最开始,匹配开 ...

  5. Yann Martell《少年 pi 的奇幻漂流》

    事情并没有像我们预想的那样发生,你能怎么办呢?无论生活以怎样的方式向你走来,你都应该勇敢地面对它,尽可能地享受它!

  6. 解决Oracle出现以0开头的小数,开头的0消失的问题

    项目中碰到了个问题,本来报表需要显示“0.49%”,结果就是显示成“.49%” 找问题 首先在pl/sql工具里执行sql,发现原始的数据就是“.49%”,那么问题来了,原始sql的问题,跟工具无关了 ...

  7. POJ 3050 Hopscotch【DFS带回溯】

    POJ 3050 题意: 1.5*5的方阵中,随意挑一格,记住这个格子的数字 2.可以上下左右走,走5次,每走一次记录下所走格子的数字 3.经过以上步骤,把所得6个数字连起来,形成一串数字.求共可以形 ...

  8. python常用内建模块--datetime

    datetime模块中的datetime类: 获取当前时间:datetime.now() 当前操作系统时区时间,date.utctime(UTC时间) 转换成时间戳:timestamp() 和具体时区 ...

  9. Java中九大内置对象

    1.Request对象 该对象封装了用户提交的信息,通过调用该对象相应的方法可以获取封装的信息,即使用该对象可以获取用户提交的信息.    当Request对象获取客户提交的汉字字符时,会出现乱码问题 ...

  10. C++雾中风景番外篇2:Gtest 与 Gmock,聊聊C++的单元测试

    正式工作之后,公司对于单元测试要求比较严格.(笔者之前比较懒,一般很少写完整的单测~~).作为一个合格的开发工程师,需要为所编写代码编写适量的单元测试是十分必要的,在实际进行的开发工作之中,TDD(T ...