1 Linux设备树概述1.1 Linux设备树概述 Linux设备树是一个包含节点和属性的简单树状结构。属性是基于key-value对的,而节点可以同时包含属性和子节点。下面这个树就是一个典型结构: / { node1 { a-string-property = "A string"; a-string-list-property = "first string", "second string"; a-byte-data-property = [0x01 0x23 0x34 0x56]; child-node1 { first-child-property; second-child-property = <1>; a-string-property = "Hello, world"; }; child-node2 { }; }; node2 { an-empty-property; a-cell-property = <1 >; /* each number (cell) is a uint32 */ child-node1 { }; }; }; 这棵树没有描述任何东西,但是它体现了节点的一些属性: l 一个单独的根节点:“/” l 两个子节点:“node1”和“node2” l 两个 node1 的子节点:“child-node1”和“child-node2” l 一堆分散在树里的属性 可以这么简单理解:节点就是树枝,属性就是树叶;树枝上可以有再长树枝也可以长树叶,而树叶上则不会再长树枝。 属性是基于key-value结构的,value可以为空或者特定格式的字符串内容。由于数据类型并不被编码到最终的数据结构中,设备树源代码中仅能支持有限的几种基本数据类型,如下: l 文本字符串(无结束符)可以用双引号表示: string-property = "a string" l 'Cells'是 32 位无符号整数,用尖括号表示: cell-property = <0xbeef xabcd> l 二进制数据用方括号表示: binary-property = [0x01 0x23 0x45 0x67]; l 不同表示形式的数据可以使用逗号连在一起: mixed-property = "a string", [0x01 0x23 0x45 0x67], <0x12345678>; l 逗号也可用于创建字符串列表: string-list = "red fish", "blue fish"; 1.2 基本概念1.2.1 初始结构第一步就是构建一个基本结构,这是一个设备树最基本的结构。在这个阶段,需要一个唯一的标识该机器。 / { compatible = "gpio-leds"; }; compatible指定了系统的名称。它包含了一个“<>,<>”形式的字符串。重要的是要指定一个确切的设备,并且包括制造商的名字,以避免命名空间冲突。由于操作系统会使用 compatible的值来决定如何在机器上运行,所以正确的设置这个属性十分重要。 1.2.2 中央处理器 第二步就是描述CPU。先添加一个名为“cpus”的容器节点,然后为每个CPU分别添加子节点,以TI AM437x平台为例: / { compatible = "ti,am437x-gp-evm"; cpus { cpu@0 { compatible = "ti,am4372"; }; cpu@1 { compatible = "ti,am4372"; }; }; }; 每个cpu节点compatible属性是一个“<>,<>”形式的字符串,并指定了确切的cpu,就像顶层的compatible属性一样。 1.2.3 节点名称 每个节点必须有一个“<>[@<>]”形式的名字。 l << span>名称>就是一个不超过31位的简单ascii字符串。通常,节点的命名应该根据它所体现的是什么样的设备。比如一个3com以太网适配器的节点就应该命名为 ethernet,而不应该是3com509。 l 如果该节点描述的设备有一个地址的话,还应该加上设备地址(unit-address)。通常,设备地址就是用来访问该设备的主地址,并且该地址也在节点的reg属性中列出。 l 同级节点命名必须是唯一的,但只要地址不同,多个节点也可以使用一样的通用名,例如serial@101f1000和serial@101f2000。 1.2.4 设备系统中每个设备都表示为一个设备树节点。所以接下来就应该为这个设备树填充设备节点。 / { compatible = "ti,am437x-gp-evm"; cpus { cpu@0 { compatible = "ti,am4372"; }; cpu@1{ compatible = "ti,am4372"; }; }; serial@101F0000 { compatible = "ti,omap2-uart"; }; serial@101F2000 { compatible = "ti,am4372-uart"; }; gpio@101F3000 { compatible = "ti,pl061"; }; spi@10115000 { compatible = "ti,ads7846"; }; external-bus { ethernet@0,0 { compatible = "ti,smc91c111"; }; i2c@1,0 { compatible = "ti,tps65218"; rtc@58 { compatible = "ti,ds1338"; }; }; flash@2,0 { compatible = "ti,omap2-nand", "omap3-nand"; } 在此树中,已经为系统中的每个设备添加了节点,而且这个层次结构也反映了设备与系统的连接方式。例如,外部总线上的设备就是外部总线节点的子节点,i2c 设备就是i2c 总线节点的子节点。通常,这个层次结构表现的是CPU视角的系统视图。 在这颗树中,应该注意这些事情: l 每个设备节点都拥有一个compatible 属性。 l flash闪存节点的compatible属性由两个字符串构成。 l 正如前面所述,节点的命名应当反映设备的类型而不是特定的型号。 1.2.5 理解compatible属性设备树中每个节点都需要一个compatible属性。compatible属性是操作系统用来决定使用哪个设备驱动来绑定到一个设备上的关键因素。 compatible是一个字符串列表,其中第一个字符串指定了这个节点所表示的确切的设备,该字符串的格式为:"<>,<>"。剩下的字符串的则表示其它与之相兼容的设备。 1.3 如何编址 可编址设备使用以下属性将地址信息编码进设备树: reg #address-cells #size-cells 每个可编址设备都有一个元组列表的reg,元组的形式为:reg = <>。每个元组都表示一个该设备使用的地址范围。每个地址值是一个或多个32位整型数列表,称为cell。同样,长度值也可以是一个 cell 列表或者为空。 由于地址和长度字段都是可变大小的变量,那么父节点的#address-cells和#size-cells 属性就用来声明各个字段的cell的数量。换句话说,正确解释一个reg属性需要用到父节点的#address-cells和#size-cells的值。
更多帮助销售邮箱:www.tronlong.com 技术论坛:www.51ele.net 线上商城:https://tronlong.taobao.com |