为AM335x移植Linux内核主线代码(5)booting-without-of.txt学习笔记中
2018-03-28 08:50
519 查看
转载地址:http://www.eefocus.com/marianna/blog/14-10/306296_feb5f.html
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.
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.
相关文章推荐
- 为AM335x移植Linux内核主线代码(6)booting-without-of.txt学习笔记下
- 为AM335x移植Linux内核主线代码(4)booting-without-of.txt学习笔记上
- 设备树(四)linux内核总线booting-without-of.txt
- 为AM335x移植Linux内核主线代码(1)了解dts
- 为AM335x移植Linux内核主线代码(2)顶层的maria_am335x.dts
- 为AM335x移植Linux内核主线代码了解dts
- 设备树(四)linux内核总线booting-without-of.txt
- 为AM335x移植Linux内核主线代码(1)了解dtb
- 为AM335x移植Linux内核主线代码
- 为AM335x移植Linux内核主线代码(3)次顶层的maria_am335x-common.dts
- 为AM335x移植Linux内核主线代码(1)了解dtb
- 为AM335x移植Linux内核主线代码(35)使用platform中的GPIO
- 为AM335x移植Linux内核主线代码(1)了解dts
- 为AM335x移植Linux内核主线代码——了解dts
- TQ2440 学习笔记—— 34、移植 Linux 内核【 Makefile 分析 】
- Linux学习笔记:内核代码编码风格
- 设备树(五)linux内核主线booting-without-of.txt
- Linux学习内核移植相关笔记第1部分
- linux 驱动学习笔记02--应用实例:在内核中新增驱动代码目录和子目录
- 设备树(五)linux内核主线booting-without-of.txt