Linux设备树(device tree)要点
总体概念:
DTS是有许多node组成的,用于描述系统的硬件。
node的一般方式是
[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
}
“[]”表示option,因此可以定义一个只有node name的空节点。label方便在dts文件中引用。child node的格式和node是完全一样的,因此,一个dts文件中就是若干嵌套组成的node,property以及child note、child note property描述。
device tree的基本单元是node。这些node被组织成树状结构,除了root node,每个node都只有一个parent。一个device tree文件中只能有一个root node。每个node中包含了若干的property/value来描述该node的一些特性。
属性(property)值标识了设备的特性,它的值(value)是多种多样的:
1、可能是空,也就是没有值的定义。
2、可能是一个u32、u64的数值(值得一提的是cell这个术语,在Device Tree表示32bit的信息单位)。例如#address-cells = <1> 。当然,可能是一个数组。例如<0x00000000 0x00000000 0x00000000 0x20000000>
3、可能是一个字符串。例如device_type = "memory" ,当然也可能是一个string list。例如"PowerPC,970"
一些常见属性:
1.compatible属性
在描述compatible属性之前要先描述model属性。model属性指明了该设备属于哪个设备生产商的哪一个model。一般而言,我们会给model赋值“manufacturer,model”。例如model = "samsung,s3c24xx"。samsung是生产商,s3c24xx是model类型,指明了具体的是哪一个系列的SOC。OK,现在我们回到compatible属性,该属性的值是string list,定义了一系列的modle(每个string是一个model)。这些字符串列表被操作系统用来选择用哪一个driver来驱动该设备。假设定义该属性:compatible = “aaaaaa”, “bbbbb"。那么操作操作系统可能首先使用aaaaaa来匹配适合的driver,如果没有匹配到,那么使用字符串bbbbb来继续寻找适合的driver,对于本例,compatible = "samsung,s3c24xx",这里只定义了一个modle而不是一个list。对于root node,compatible属性是用来匹配machine type的(在device tree代码分析文章中会给出更细致的描述)。对于普通的HW block的节点,例如interrupt-controller,compatible属性是用来匹配适合的driver的。
2. reg属性:reg = <address1 length1 [address2 length2] [address3 length3] ... > ;reg中的address和length需要多少个32bit(cell)描述是分别用父节点中的#address-cells和#size-cells指定的。reg属性定义了访问该device node的地址信息,该属性的值被解析成任意长度的(address,size)数组,具体用多长的数据来表示address和size是在其parent node中定义(#address-cells和#size-cells)。对于device node,reg描述了memory-mapped IO register的offset和length。对于memory node,定义了该memory的起始地址和长度。
3. ranges属性:包含三个信息,分别是the child's #address-cells
value, the parent's #address-cells
value, and the child's #size-cells
value。主要将设备的本地地址映射到CPU能访问的地址。
ranges属性值的格式 <local地址, parent地址, size>, 表示将local地址向parent地址的转换。比如对于#address-cells和#size-cells都为1的话,以<0x0 0x10 0x20>为例,表示将local的从0x0~(0x0 + 0x20)的地址空间映射到parent的0x10~(0x10 + 0x20)
例子:ranges描述nor flash的地址空间,注意不是描述nfand flash,因为两者寻址的差异,nor fash是直接和地址总线上统一编址的,nand要经过控制器才能访问,类似硬盘。
ranges描述pci地址空间时,phys.hi cell的含义
phys.hi cell: npt000ss bbbbbbbb dddddfff rrrrrrrr
具体见参考
参考:
https://elinux.org/Device_Tree_Usage
http://www.wowotech.net/linux_kenrel/dt_basic_concept.html