繁体   English   中英

了解设备树机制

[英]Understanding the Device Tree mechanism

正在阅读设备树用法并到达描述节点的ranges键属性的部分。

external-bus {
        #address-cells = <2>
        #size-cells = <1>;
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

        ethernet@0,0 {
            compatible = "smc,smc91c111";
            reg = <0 0 0x1000>;
            interrupts = < 5 2 >;
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <1 0 0x1000>;
            interrupts = < 6 2 >;
            rtc@58 {
                compatible = "maxim,ds1338";
                reg = <58>;
                interrupts = < 7 3 >;
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
            reg = <2 0 0x4000000>;
        };
    };
  1. rangesreg什么区别?
  2. 范围的尺寸是多少,解析器如何找出其中写入的内容?
  3. 我还没有理解的缺失部分? 不能在.dts文件中包含.h文件而不是硬编码值?

“范围”属性将当前节点“外部总线”节点中的一个或多个地址(范围左侧的第二个数字)映射到父节点(可能是 CPU)地址空间中的地址(第三个数字)范围内)。 第四个数字是范围的长度。 总线可以有自己的关于外围设备所连接的外部地址的想法,因此管理总线上的外围设备的驱动程序需要知道这些范围,以便从设备读取或写入。

“reg”属性指示设备所在节点(在本例中为“外部总线”)的地址范围内的地址,在该节点定义设备。 因此在这种情况下, flash@2,0驻留在外部总线范围内的地址 0,并扩展到地址 0x04000000。 这对应于父 (CPU) 地址空间中的地址范围 0x30000000 到 0x34000000。

我假设第三个范围的长度说明符2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash 2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash实际上应该是0x04000000而不是0x1000000

对于这个特定的例子,Jonathan Ben-Avraham 的解释是正确的。 但是了解设备树中ranges属性的详细结构是很好的。

  • 范围是地址转换的列表。
  • 范围表中的每个条目都是一个元组,包含子地址父地址和子地址空间中区域的大小

喜欢

ranges = < Child1Address ParentAddressForChild1 sizeofchild1 
           Child2Address ParentAddressForChild2 sizeofchild2
           Child3Address ParentAddressForChild3 sizeofchild3
>;
  • 每个字段的大小确定如下

为了获取子节点的地址大小,请检查子节点的#address-cells值。

要计算父地址大小,请检查其父节点的#address-cells值,

为了取大小检查子节点的#size-cells值的长度。


示例 1:作为问题提及

    #address-cells = <1>;
    #size-cells = <1>;
    external-bus {
        #address-cells = <2>;
        #size-cells = <1>;
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

让我们解码第一个条目。

  1. 子地址单元格大小为 2,因此前两个条目提及子地址。 (此地址仅特定于本地子寻址)此外,如何解码这 2 个条目是特定于设备的。 设备驱动程序应该有这些文档)
  2. 父地址单元格大小为 1,因此下一个条目是该子项的父地址。
  3. child size-cells 是 1 所以下一个条目是 child 的范围(wrt to parent address。)

示例 2:PCI 设备入口

#address-cells = <1>;
#size-cells = <1>;
pci@0x10180000 {
    compatible = "arm,versatile-pci-hostbridge", "pci";
    reg = <0x10180000 0x1000>;
    interrupts = <8 0>;
    bus-range = <0 0>;

    #address-cells = <3>
    #size-cells = <2>;
    ranges = <0x42000000 0 0x80000000 0x80000000 0 0x20000000
              0x02000000 0 0xa0000000 0xa0000000 0 0x10000000
              0x01000000 0 0x00000000 0xb0000000 0 0x01000000>;

这里

0x42000000 0 0x80000000 是 child1 的地址。 PCI 驱动程序文档中提到了如何解码这 3 个条目。

0x80000000 是父地址。 父节点是 cpu,所以从 cpu 这个地址用来和这个 devide 对话。

0 0x20000000 是该设备在父地址空间中的大小。 (0 到 512MB 的地址)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM