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位而已