A node has 2 names. The actual node name is generally contained in a
property of type "name" in the node property list whose value is a zero
terminated string and is mandatory for version 1 to 3 of the format
definition (as it is in Open Firmware). Version 16 makes it optional as
it can generate it from the unit name defined below.
***********************************************
练习题:观察一颗device-tree,看看它有什么特点?
/ {
model = "TI AM335x maria_am335x";
compatible = "ti,maria_am335x", "ti,am33xx";
cpus {
cpu@0 {
cpu0-supply = <&dcdc2_reg>;
};
};
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>; /* 512 MB */
};
leds {
pinctrl-names = "default";
pinctrl-0 = <&user_leds_s0>;
compatible = "gpio-leds";
led@2 {
label = "maria_335x:red:usr_led0";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
linux,default-trigger = "";
default-state = "off";
};
};
};
每个大括号都认为是一个node,根node是"/"。
led@2也是一个node。
每个node都有两个name。在verrion 1 to 3中,actual node name存储在特征
名字里;而在version 16之后的版本,会自动从unit name中生成。
***********************************************
There is also a "unit name" that is used to differeniate nodes with the
same name at the same level, it is usually made of the node names, the
"@" sign, and a "unit address", which definition is specific to the bus
type the node sits on.
The unit name doesn't exist as a property per-se but is included in the
device-tree structure. It is typically used to represent "path" in the
device-tree. More details about the actual format of these will be below.
***********************************************
练习题:观察一颗device-tree,看看它有什么特点?
led@2 {
label = "maria_335x:red:usr_led0";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
linux,default-trigger = "";
default-state = "off";
};
led@2就是unit name,除了2之外,还另外定义了3个led节点。
ps:Cadsoft Eagle软件,也是使用@这种方式区分不同的原理图Pin脚!
***********************************************
The kernel generic code does not make any formal use of the unit address
(though some board support code may do) so the only real requirement here
for the unit address is to ensure uniqueness of the node unit name at a
given level of the tree. Nodes with no notion of address and no possible
sibling of the same name (like /memory or /cpus) may omit the unit
address in the context of this specification, or usr the "@0" default
unit address. The unit name is used to define a node "full path", which
is the concatenation of all parent node unit names separated with "/".
The root node doesn't have a defined name, and isn't required to have
a name property either if you are using version 3 or earlier of the
format. It also has no unit address (no @ symbol followed by a unit
address). The root node unit name is thus an empty string. The full
path to the root node is "/".
***********************************************
练习题:观察一颗device-tree,看看它有什么特点?
/ {
model = "TI AM335x maria_am335x";
compatible = "ti,maria_am335x", "ti,am33xx";
cpus {
cpu@0 {
cpu0-supply = <&dcdc2_reg>;
};
};
};
"/"就是根node。
它不包含任何其它的字符。
***********************************************
Every node which actually represents an actual device (that is, a node
which isn't only a virtual "container" for more nodes, like "/cpus"
is) is also required to have a "compatible" property indicating the
specific hardware and an optional list of devices it is fully backwards
compatible with.
***********************************************
练习题:观察一颗device-tree,看看它有什么特点?
leds {
pinctrl-names = "default";
pinctrl-0 = <&user_leds_s0>;
compatible = "gpio-leds";
led@2 {
label = "maria_335x:red:usr_led0";
gpios = <&gpio1 16 GPIO_ACTIVE_LOW>;
linux,default-trigger = "";
default-state = "off";
};
};
关键字compatible,是驱动程序调用实际硬件的关键。
在drivers/leds/leds-gpio.c中,有一个函数:
static const struct of_device_id of_gpio_leds_match[] = {
{ .compatible = "gpio-leds", },
{},
};
driver/leds/leds-gpio.c是驱动文件,从这里就可以看出,dtb文件是怎样
和驱动程序联系起来的。这个文件底下有熟悉的关键字:
MODULE_AUTHOR
MODULE_DESCRIPTION
MODULE_LICENSE
MODULE_ALIAS
是的,它是一个模块文件,生成的设备以及它的read/write/ioctl等等函数正
是应用程序所需要的!
***********************************************
Finally, every node that can be referenced from a property in another
node is required to have either a "phandle" or a "linux,phandle"
property. Real Open Firmware implementations provide a unique "phandle"
value for every node that the "prom_init()" trampoline code turns into
"linux,phandle" properties. However, this is made optional if the
flattened device tree is used directly. An example of a node referencing
another node via "phandle" is when laying out the interrupt tree which
will be described in a further version of this document.
The "phandle" property is a 32-bit value that uniquely identified a node
followed by the node unit name. You are free to use whatever values or
system of values, internal pointers, or whatever to generate these, the
only requirement is that every node for which you provide that property
has a unique value for it.
Here is an example of a simple device-tree. In this example, an "o"
designates a node followed by the node unit name. Properties are
presented with their name followed by their content. "content" represents
an ASCII string (zero terminated) value, while <content> represents an
32-bit value, specified in decimal or hexadecimal (the latter prefixed
0x). The various nodes in this example will be discussed in a later
chapter. At this point, it is only meant to give you a idea of what a
device-tree looks like. I have purposelly kept the "name" and
"linux,phandle" properties which aren't necessary in order to give you
a better idea of what the tree looks like in practice.
/ o device-tree
|- name = "device-tree"
|- model = "MyBoardName"
|- compatible = "MyBoardFamilyName"
|- #address-cells = <2>
|- #size-cells = <2>
|- linux,phandle = <0>
|
o cpus
| | - name = "cpus"
| | - linux,phandle = <1>
| | - #address-cells = <1>
| | - #size-cells = <0>
| |
| o PowerPC,970@0
| |- name = "PowerPC,970"
| |- device_type = "cpu"
| |- reg = <0>
| |- clock-frequency = <0x5f5e1000>
| |- 64-bit
| |- linux,phandle = <2>
|
o memory@0
| |- name = "memory"
| |- device_type = "memory"
| |- reg = <0x00000000 0x00000000 0x00000000 0x20000000>
| |- linux,phandle = <3>
|
o chosen
|- name = "chosen"
|- bootargs = "root=/dev/sda2"
|- linux,phandle = <4>
This tree is almost a minimal tree. It pretty much contains the minimal
set of required nodes and properties to boot a linux kernel; that is,
some basic model information at the root, the CPUs, and the physical
memory layout. It also includes misc information passed through /chosen,
like in this example, the platform type (mandatory) and the kernel
command line arguments (optional).
The /cpus/PowerPC,970@1/64-bit property is an example of a property
without a value. All other properties have a value. The significance of
the #address-cells and #size-cells properties will be explained in
chapter IV which defined precisely the required nodes and properties and
their content.
***********************************************
练习题:phandle的特点是什么呢?
答:关于phandle,俺是真心没看懂-_-!!!
***********************************************
3) Device tree "structure" block
The structure of the device tree is a linearized tree structure. The
"OF_DT_BEGIN_NODE" token starts a new node, and the "OF_DT_END_NODE"
ends that node definition. Child nodes are simply defined before
"OF_DT_END_NODE" (that is nodes within the node). A 'token' is a 32 bit
value. The tree has to be "finished" with a OF_DT_END token
Here's the basic structure of a single node:
* token OF_DT_BEGIN_NODE (that is 0x00000001)
* for version 1 to 3, this is the node full path as a zero
terminated string, starting with "/". For version 16 and later,
this is the node unit name only (or an empty string for the
root node)
* [align gap to next 4 bytes boundary]
* for each property:
* token OF_DT_PROP (that is 0x00000003)
* 32-bit value of property value size in bytes (or 0 if
no value)
* 32-bit value of offset in string block of property name
* property value data if any
* [align gap to next 4 bytes boundary]
* [child nodes data if any]
* token OF_DT_END_NODE (that is 0x00000002)
So the node content can be summarized as a start token, a full path, a
list of properties, a list of child nodes, and an end token. Every child
node is a full node structure itself as defined above.
***********************************************
练习题:token在哪里?
答:在Linux Kernel的源代码中,grep -rn OF_DT_BEGIN_NODE
在下面的文件中存在:
arch/powerpc/platforms/powermac/bootx_init.c
arch/powerpc/include/asm/prom.h
arch/powerpc/kernel/prom_init.c
而在dts文件中并没有出现,说明这些token并不是给用户编写程序使用的,而是经过编译
器编译之后在dtb文件里面被内核识别。
***********************************************
NOTE: The above definition requires that all property definitions for a
particular node MUST precede any subnode definitions for that node.
Although the structure would not be ambiguous if properties and subnodes
were intermingled, the kernel parser requires that the properties come
first (up until at least 2.6.22). Any tools manipulating a flattened
tree must take care to preserve this constraint.
4) Device tree "strings" block
In order to save space, property names, which are generally redundant,
are stored separately in the "strings" block. This block is simply the
whole bunch of zero terminated strings for all property definitions in
the structure block will contain offset values form the beginning of
the string block.
DiracFatCat 2014-10-23 10:48
用户403664 2014-10-23 10:41