您的位置:首页 > 运维架构 > Linux

为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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: