Device Tree 配置参数

Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子结点。所谓属性,其实就是成对出现的name和value。
如果要使用Device Tree,首先用户要了解自己的硬件配置和系统运行参数,并把这些信息组织成Device Tree source file。
Device Tree将会被通过DTC(Device Tree Compiler)编译成适合机器处理的DTB(device tree blob)文件。
Device Tree不是必须要描述系统中的所有硬件信息,可以动态探测到的设备是不需要描述的,但是无法动态识别的,需要在device tree中描述。例如,USB device不需要描述,usb host controller不能被探测,需要描述。
下面给出一个Device Tree的模版:
/  
  name = "device-tree" 
  model = "MyBoardName" 
  compatible = "MyBoardFamilyName" 
  #address-cells = <2> 
  #size-cells = <2> 
  linux,phandle = <0>  
  chosen {
   name = "chosen" 
   bootargs = "root=/dev/sda2" 
   linux,phandle = <4>
   }
  cpus {
    #address-cells = <1>;
    #size-cells = <0>;
    cpu0:cpu@0x000 {
        device_type = "cpu";
        compatible = "arm,cortex-a7";
        reg = <0x000>;
        clock-latency = <40000>;
        clocks = <&cru ARMCLK>;
        resets = <&cru SRST_CORE0>;
    };
    memory {
    device_type = "memory";
    reg = <0x60000000 0x40000000>;
};
分析上面给出的例子,总结一下几点:
1、device tree的基本单元是node。这些node被组织成树状结构,root node的node name是确定的,必须是“/”。除了root node,每个node都只有一个parent。一个device tree文件中只能有一个root node。
2、每个node中包含了若干的property/value来描述该node的一些特性。
2-1、每个node用节点名字(node name)标识,节点名字的格式是node-name@unit-address。
2-2、如果该node没有reg属性(后面会描述这个property),那么该节点名字中必须不能包括@和unit-address。
2-3、对于cpu,其unit-address就是从0开始编址,以此加一。而具体的设备,其unit-address就是寄存器地址。
3、在一个树状结构的device tree中,要想唯一指定一个node必须使用full path。在上面的例子中,cpu node我们可以通过/cpus/cpu@0x000访问。
4、属性:
4-1、可能是空,也就是没有值的定义。
4-2、属性值是32bit unsigned integers可能是一个u32、u64的数值(值得一提的是cell这个术语,在Device Tree表示32bit的信息单位)。例如#address-cells = <1> 。如果一个device node中包含了有寻址需求(要定义reg property),那么就必须要定义#address-cells和#size-cells这两个属性
4-3、属性值是text string或者string list,可能是一个字符串。例如device_type = "cpu";

一个node被定义成如下:
[label:] node-name[@unit-address] { 
   [properties definitions] 
   [child nodes] 
}
“[]”表示option,label方便在dts文件中引用,一个dts文件可以嵌套多个node,并且可以通过include xxx.dtsi来包含其他的node(如果包含,dti中的内容将把dtsi覆盖)
其中的相关的规则如下:
1、aliases 节点定义了一些别名。(当要引用一个node的时候要指明相对于root node的full path,如果多次引用,每次都要写这么复杂的字符串多少是有些麻烦,因此可以在aliases 节点定义一些设备节点full path的缩写。)
2、memory device node是所有设备树文件的必备节点,它定义了系统物理内存的layout。reg定义了该memory的起始地址和长度。其device_type必须等于memory。
3、device_type属性定义了该node的设备类型,例如cpu、serial等。
4、reg属性定义了访问该device node的地址信息,该属性的值被解析成任意长度的(address,size)数组,具体用多长的数据来表示address和size是在其parent node中定义(#address-cells和#size-cells)。reg描述了memory-mapped IO register的offset和length。
5、model属性指明了该设备属于哪个设备生产商的哪一个model。
6、compatible属性,该属性的值是string list,定义了一系列的modle(每个string是一个model)。这些字符串列表被操作系统用来选择用哪一个driver来驱动该设备。compatible的作用就是,在uboot中的代码能通过compatible属性match到dts相同的driver。uboot代码内容如下:
static const struct udevice_id rockchip_gpio_ids[] = {
{ .compatible = "rockchip,gpio-bank" },
{ }
};
U_BOOT_DRIVER(gpio_rockchip) = {
.name   = "gpio_rockchip",
.id = UCLASS_GPIO,
.of_match = rockchip_gpio_ids,
.ops    = &gpio_rockchip_ops,
.priv_auto_alloc_size = sizeof(struct rockchip_gpio_priv),
.probe  = rockchip_gpio_probe,
};
Device Tree显示的内容如下:
  gpio0: gpio0@2007c000 {
        compatible = "rockchip,gpio-bank";
        reg = <0x2007c000 0x100>;
    interrupts = <GIC_SPI 36  IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru PCLK_GPIO0>;
        gpio-controller;
        #gpio-cells = <2>;
        interrupt-controller;
        #interrupt-cells = <2>;
    };
7、在dts文件中是用interrupt-parent这个属性来标识,使interrupt source物理连接到interruptcontroller。因为能够产生中断的device node没有定义interrupt-parent的话,其interrupt-parent属性就是跟随parent node。因此,与其在所有的下游设备中定义interrupt-parent,不如统一在root node中定义了。
8、interrupts属性有三个
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
第一个member表示该 interrupt 是 SPI 还是 PPI。
第二个member就是具体的中断号了。查阅SoC的手册就可以得到。(36 = number - 32)
第三个member指的是中断的触发方式,每个SoC是不同的,查阅SoC的手册就可以知道了。
9、dmas = <&pdma 2>, <&pdma 3>;dma地址和dma通道选择
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值