Linux设备树的用法(3)

比如,Freescale MPC8349有一个串口设备是由National Semiconductor ns16550寄存器接口来实现的。所以对MPC8349的串口设备,它的compatible属性我们就可以这样写:compatible = "fsl,mpc8349-uart", "ns16550",对于这样的情况,fsl,mpc8349-uart准确描述了这个设备,而ns16550则说明了这个设备是与National Semiconductor ns16550寄存器接口兼容的。

注:ns16550它没有厂商名这个信息,这是由于历史原因。但所有新创建的compatible属性都应该有厂商名这个前缀。

compatible属性的这一特性,使得我们可以让新设备使用系统中已有的旧驱动。

警告:不要在compatible属性中使用通配符,如 "fsl,mpc83xx-uart" 或类似的。因为半导体厂商会不定期的更新他们的设计这会破坏你的通配符规则。选择具有更好兼容性的方案才是正途。

 

地址是怎么工作的

可寻址设备是通过使用以下属性来将地址信息编码到设备树中的:

reg

#address-cells

#size-cells

可寻址设备通过reg属性来获取寄存器相关的地址信息列表,reg属性的形式如下:

reg = <address1 length1 [address2 length2] [address3 length3] ... >

每一组address length对应了设备所使用的一个地址区域。

address是一个list,其中包含一个或多个32位整数,我们把它叫做 cells。同理,length也是一个list,可以是多个cell或为空。

 

由于address和length的长度都是不固定的,所以有了#address-cells#size-cells这两个属性。这两个属性被放到父节点中用于描述每个区域有几个cell。简单的说,就是reg属性需要配合父节点的#address-cells#size-cells来配合使用。为了弄明白它们是怎么工作的,下面我们就来为这个设备加上地址相关的属性,先从CPU开始。

 

CPU地址

CPU节点的地址用法是最简单的。每个CPU被分配了唯一的ID号,而且这个没有size。

    cpus {

        #address-cells = <1>;

        #size-cells = <0>;

        cpu@0 {

            compatible = "arm,cortex-a9";

            reg = <0>;

        };

        cpu@1 {

            compatible = "arm,cortex-a9";

            reg = <1>;

        };

    };

 

在上面的cpus节点中,#address-cells被设为了1,#size-cells则被设为了0,这就表示它的子节点中的reg属性是一个32位整数的address,而且没有size部分。

在上面的例子中,你可能注意到了节点名中的寄存器地址与reg数值一样。

约定俗成的做法是,如果一个节点有reg属性,则节点名中也需要包含unit-address这个部分,而unit-address的数值则是reg属性的第一个address值。

 

内存映射设备

与cpu节点中的这种单地址不同,内存映射设备所分配的是一个地址范围,而这个地址范围则是由#size-cells和节点中的reg属性的size区域来决定的。下面这个例子中,每个address是1个cell(32bit),且每个长度值也是一个cell。在32位系统中#size-cells通常就是这样设置为1的。而早64位系统中,#address-cells#size-cells则通常设置为2。

/ {

    #address-cells = <1>;

    #size-cells = <1>;

 

    ...

 

    serial@101f0000 {

        compatible = "arm,pl011";

        reg = <0x101f0000 0x1000 >;

    };

 

    serial@101f2000 {

        compatible = "arm,pl011";

        reg = <0x101f2000 0x1000 >;

    };

 

    gpio@101f3000 {

        compatible = "arm,pl061";

        reg = <0x101f3000 0x1000

               0x101f4000 0x0010>;

    };

 

    interrupt-controller@10140000 {

        compatible = "arm,pl190";

        reg = <0x10140000 0x1000 >;

    };

 

    spi@10115000 {

        compatible = "arm,pl022";

        reg = <0x10115000 0x1000 >;

    };

 

    ...

 

};

 

每个设备被分配了一个基地址以及一个size。上面的例子中,gpio设备被分配了两个地址段: 0x101f3000~0x1013fff 以及 0x101f4000~0x101f4fff。

 

有些设备在系统总线上的地址不连续。比如,一个设备可能通过不连续的片选线连接在外部总线上。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/6c0fc219b0ea511bacee7c6ba4b1058e.html