您好,欢迎访问三七文档
设备树使用手册本文将介绍如何为一个新机器编写设备树。我们准备提供一个有关设备树概念的概述和如何使用这些设备树来描述一个机器。完整的设备树数据格式的技术说明书请参考ePAPR规范。ePAPR规范涵盖了比本文基本主题更丰富的细节,要查阅本文没有涉及到的高级用法请参考该规范。目录1.基本数据格式2.基本概念2.1模型机2.2初始结构2.3中央处理器2.4节点名称2.5设备2.6理解compatible属性3.如何编址3.1CPU编址3.2内存映射设备3.3非内存映射设备3.4范围(地址转换)4.中断的工作方式5.设备特定数据6.特殊的节点6.1aliases节点6.2chosen节点7.高级主题7.1高级模型机7.2PCI主桥7.2.1PCI总线编号7.2.2PCI地址转换7.3高级中断映射8.附注基本数据格式设备树是一个包含节点和属性的简单树状结构。属性就是键-值对,而节点可以同时包含属性和子节点。例如,以下就是一个.dts格式的简单树:/{node1{a-string-property=Astring;a-string-list-property=firststring,secondstring;a-byte-data-property=[0x010x230x340x56];child-node1{first-child-property;second-child-property=1;a-string-property=Hello,world;};child-node2{};};node2{an-empty-property;a-cell-property=1234;/*eachnumber(cell)isauint32*/child-node1{};};};这棵树显然是没什么用的,因为它并没有描述任何东西,但它确实体现了节点的一些属性:■一个单独的根节点:“/”■两个子节点:“node1”和“node2”■两个node1的子节点:“child-node1”和“child-node2”■一堆分散在树里的属性。属性是简单的键-值对,它的值可以为空或者包含一个任意字节流。虽然数据类型并没有编码进数据结构,但在设备树源文件中任有几个基本的数据表示形式。■文本字符串(无结束符)可以用双引号表示:string-property=astring■‘Cells’是32位无符号整数,用尖括号限定:cell-property=0xbeef1230xabcd1234■二进制数据用方括号限定:binary-property=[0x010x230x450x67];■不同表示形式的数据可以使用逗号连在一起:mixed-property=astring,[0x010x230x450x67],0x12345678;■逗号也可用于创建字符串列表:string-list=redfish,bluefish;基本概念我们将以一个简单机开始,然后通过一步步的建立一个描述这个简单机的设备树,来了解如何使用设备树。2.1模型机考虑下面这个假想的机器(大致基于ARMVersatile),制造商为“Acme”,并命名为“Coyote'sRevenge”:■一个32位ARMCPU■处理器本地总线连接到内存映射的串行口、spi总线控制器、i2c控制器、中断控制器和外部总线桥■256MBSDRAM起始地址为0■两个串口起始地址:0x101F1000和0x101F2000■GPIO控制器起始地址:0x101F3000■带有以下设备的SPI控制器起始地址:0x10170000■MMC插槽的SS管脚连接至GPIO#1■外部总线桥挂载以下设备■SMCSMC91111以太网设备连接到外部总线,起始地址:0x10100000■i2c控制器起始地址:0x10160000,并挂载以下设备■MaximDS1338实时时钟。响应至从地址1101000(0x58)■64MBNOR闪存起始地址0x300000002.2初始结构第一步就是要为这个模型机构建一个基本结构,这是一个有效的设备树最基本的结构。在这个阶段你需要唯一的标识该机器。/{compatible=acme,coyotes-revenge;};compatible指定了系统的名称。它包含了一个“制造商,型号”形式的字符串。重要的是要指定一个确切的设备,并且包括制造商的名子,以避免命名空间冲突。由于操作系统会使用compatible的值来决定如何在机器上运行,所以正确的设置这个属性变得非常重要。理论上讲,兼容性(compatible)就是操作系统需要的所有数据都唯一标识一个机器。如果机器的所有细节都是硬编码的,那么操作系统则可以在顶层的compatible属性中具体查看“acme,coyotes-revenge”。2.3中央处理器接下来就应该描述每个CPU了。先添加一个名为“cpus”的容器节点,然后为每个CPU分别添加子节点。具体到我们的情况是一个ARM的双核CortexA9系统。/{compatible=acme,coyotes-revenge;cpus{cpu@0{compatible=arm,cortex-a9;};cpu@1{compatible=arm,cortex-a9;};};};每个cpu节点的compatible属性是一个“制造商,型号”形式的字符串,并指定了确切的cpu,就像顶层的compatible属性一样。稍后将会有更多的属性添加进cpu节点,但我们先得讨论一些更过的基本概念。2.4节点名称现在应该花点时间来讨论命名约定了。每个节点必须有一个“名称[@设备地址]”形式的名字。名称就是一个不超过31位的简单ascii字符串。通常,节点的命名应该根据它所体现的是什么样的设备。比如一个3com以太网适配器的节点就应该命名为ethernet,而不应该是3com509。如果该节点描述的设备有一个地址的话就还应该加上设备地址(unit-address)。通常,设备地址就是用来访问该设备的主地址,并且该地址也在节点的reg属性中列出。本文档中我们将在稍后涉及到reg属性。同级节点命名必须是唯一的,但只要地址不同,多个节点也可以使用一样的通用名称(例如serial@101f1000和serial@101f2000)。关于节点命名的更多细节请参考ePAPR规范2.2.1节。2.5设备系统中每个设备都表示为一个设备树节点。所以接下来就应该为这个设备树填充设备节点。现在,知道我们讨论如何进行寻址和中断请求如何处理之前这些新节点将一直为空。/{compatible=acme,coyotes-revenge;cpus{cpu@0{compatible=arm,cortex-a9;};cpu@1{compatible=arm,cortex-a9;};};serial@101F0000{compatible=arm,pl011;};serial@101F2000{compatible=arm,pl011;};gpio@101F3000{compatible=arm,pl061;};interrupt-controller@10140000{compatible=arm,pl190;};spi@10115000{compatible=arm,pl022;};external-bus{ethernet@0,0{compatible=smc,smc91c111;};i2c@1,0{compatible=acme,a1234-i2c-bus;rtc@58{compatible=maxim,ds1338;};};flash@2,0{compatible=samsung,k8f1315ebm,cfi-flash;};};};在此树中,已经为系统中的每个设备添加了节点,而且这个·层次结构也反映了设备与系统的连接方式。例如,外部总线上的设备就是外部总线节点的子节点,i2c设备就是i2c总线节点的子节点。通常,这个层次结构表现的是CPU视角的系统视图。现在这棵树还是无效的,因为它缺少关于设备之间互联的信息。稍后将添加这些信息。在这颗树中,应该注意这些事情:■每个设备节点都拥有一个compatible属性。■闪存(flash)节点的compatible属性由两个字符串构成。欲知为何,请阅读下一节。■正如前面所述,节点的命名应当反映设备的类型而不是特定的型号。请查阅ePAPR规范第2.2.2节里定义的通用节点名,应当优先使用这些节点名。2.6理解compatible属性树中每个表示一个设备的节点都需要一个compatible属性。compatible属性是操作系统用来决定使用哪个设备驱动来绑定到一个设备上的关键因素。compatible是一个字符串列表,之中第一个字符串指定了这个节点所表示的确切的设备,该字符串的格式为:制造商,型号。剩下的字符串的则表示其它与之相兼容的设备。例如,FreescaleMPC8349片上系统(SoC)拥有一个实现了美国国家半导体ns16550的寄存器接口的串行设备,那么MPC8349的串行设备的compatible属性就应该是:compatible=fsl,mpc8349-uart,ns16550。在这里,mpc8349-uart指定了确切的设备,而ns16550则说明这是与美国国家半导体ns16550UART的寄存器级兼容。注:ns16550并没有制造商前缀,这仅仅是历史原因造成的。所有的新compatible值都应该使用制造商前缀。这种做法可以使现有的设备驱动能够绑定到新设备上,并仍然唯一的指定确切的设备。警告:不要使用带通配符的compatible值,比如“fsl,mpc83xx-uart”或类似情况。芯片提供商无不会做出一些能够轻易打破你通配符猜想的变化,这时候在修改已经为时已晚了。相反,应该选择一个特定的芯片然后是所有后续芯片都与之兼容。如何编址可编址设备使用以下属性将地址信息编码进设备树:■reg■#address-cells■#size-cells每个可编址设备都有一个元组列表的reg,元组的形式为:reg=地址1长度1[地址2长度2][地址3长度3]...。每个元组都表示一个该设备使用的地址范围。每个地址值是一个或多个32位整型数列表,称为cell。同样,长度值也可以是一个cell列表或者为空。由于地址和长度字段都是可变大小的变量,那么父节点的#address-cells和#size-cells属性就用来声明各个字段的cell的数量。换句话说,正确解释一个reg属性需要用到父节点的#address-cells和#size-cells的值。要知道这一切是如何运作的,我们将给模型机添加编址属性,就从CPU开始。3.1CPU编址CPU节点表示了一个关于编址的最简单的例子。每个CPU都分配了一个唯一的ID,并且没有CPUid相关的大小信息。cpus{#address-cells=1;#size-cells=0;cpu@0{compatible=arm,cortex-a9;reg=0;};cpu@1{compatible=arm,cortex-a9;reg=1;};};在cpu节点中,#address-cells设置为1,#size-cells设置为0。这意味着子节点的reg值是一个单一的uint32,这是一个不包含大小字段的地址,为这两个cpu分配的地址是0和1。cpu节点的#size-cells为0是因为只为每个cpu分配一个单独的地址。你可能还会注意到reg的值和节点名字是相同的。按照惯例,如果一个节点有reg属性,那么该节点的名字就必须包含设备地址,这个设备地址就是reg属性里第一个地址值。3.2内存映射设备与cpu节点里单一地址值不同,应该分配给内存映射设备一个地址范围。#size-cells声明每个子节点的reg元组中长度字段的大小。在接下来的例子中,每个地址值是1cell(32位),每个长度值也是1cell,这是典型的32位系统。6
本文标题:设备树使用手册
链接地址:https://www.777doc.com/doc-2065265 .html