linux下设备树ranges属性详细介绍:
我们在设备树中ranges属性和#address-cells = <1>;#size-cells = <1>;相关联的
#address-cells属性:
#address-cells告诉你我们的地址是32为还是64位 #address-cells = <1>;就是说你的地址是32位,#address-cells = <2>;就是说你的地址是64位,现在的设备树中表示地址范围的#address-cells还没有超过2的 #address-cells只能是1和2
例如:
对于32位的地址#address-cells = <1>:
reg = <0x02000000 0x10000>这种情况我们很常见了就是 0x02000000~0x02000000+0x10000地址空间
对于64位的地址#address-cells = <2>:
reg = <0x10000000 0x02000000 0x10000>这种情况我们64位的地址就是高32位是0x10000000,低32位是0x02000000的64位地址所以他代表的地址空间就是:0x1000000002000000 + 0x10000的地址空间
#size-cells属性:表示地址大小范围,这个都能理解
理解上边两个属性,ranges的属性就好理解了
:
举个例子
imx6{
#address-cells = <1>;
#size-cells = <1>;
weim {
#address-cells = <2>;
#size-cells = <1>;
status = "okay";
/* weim memory map: 32MB on CS0, 32MB on CS1, 32MB on CS2 */
ranges = <0 0 0x08000000 0x02000000
1 0 0x0a000000 0x02000000
2 0 0x0c000000 0x02000000>;
/* TL16C554 on CS0 */
uarta0@0,0xe000 {
/* 8250 based simple serial driver */
compatible = "ti,tl16c554", "ns16550a";
reg = <0 0xe000 0x8>;
interrupt-parent = <&gpio4>;
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <3686400>;
}
uarta1@1,0xe000 {
/* 8250 based simple serial driver */
compatible = "ti,tl16c554", "ns16550a";
reg = <1 0xe000 0x8>;
interrupt-parent = <&gpio4>;
interrupts = <6 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <3686400>;
}
}
}
ranges就是地址翻译,他的成员组成如下:
ranges = <local_address parent_address address_size>
local_address:这里local_address就是我们设备树中weim节点的#address-cells = <2>;就是64位地址
parent_address:这里就是我们imx6节点的#address-cells = <1>;就是32位的地址
address_size:就是#size-cells = <1>;
所以上边我们ranges可以映射的地址空间就是:
0地址空间就是:0x08000000~0x08000000+0x02000000
1地址空间就是:0x0a000000~0x0a000000+0x02000000
2地址空间就是:0x0c000000~0x0c000000+0x02000000
所以我们节点uarta0地址空间的计算方法就是 0x08000000 + (0<<32)|(0xe000) - ((0<<32)|(0)) 就是0x0800e0000~0x0800e0008,计算方法和uart1一样
所以我们节点uarta1地址空间的计算方法就是 0x0a000000 + (1<<32)|(0xe000) - ((1<<32)|(0)) 就是0x0a00e0000~0x0a00e0008
下边我们位移是按64位来做的:
off1=这里(1<<32)|(0xe000)就是我们uarta1中reg属性前两个数字组成的64位地址(即0x1代表高32位,0xe000代表低32位)
off2=这里((1<<32)|(0))就是我们ranges=<1 0 0x0a000000 0x02000000>的前两个数字组成的64位地址,(即0x1代表高32位,0x0代表低32位)
所以我们uarta1的地址空间就是0x0a000000 + off1-off2
对于#address-cells = <1>;的情况和上边一样只是地址是32位而已