设备树实验
通过上一节基本语法的学习,这次通过实战去联系一下设备树的描写
-
初始结构
- 关键字compatible用于说明节点的名称,前三行就是描述出厂商和产品名字的
-
添加cpu
-
这里添加两个cpu
-
都是arm cortex-a9框架的
(我的这个才是a7单核的,,,酸了酸了酸了
-
每个
}
后面一定要跟分号**;
**
-
/ {
compatible = "acme,coyotes-revenge";
cpus{
cpu@0{
compatible = "arm,cortex-a9";
};
cpu@1{
compatible = "arm,cortex-a9";
};
};
};
-
添加设备
- 为每个节点添加设备
- 比如串口,i2c
serial@101F2000 { compatible = "arm,pl011"; };
- 比如这段中,串口的起始地址是101F2000
- pl011应该是虚拟地址
/ { compatible = "acme,coyotes-revenge"; cpus{ cpu@0{ compatible = "arm,cortex-a9"; }; cpu@1{ compatible = "arm,cortex-a9"; }; }; serial@101F1000 { compatible = "arm.pl011"; }; serial@101F2000 { compatible = "arm,pl011"; }; interrupt-controller@10140000 { compatible = "arm,pl190"; }; spi@10115000 { compatible = "arm,pl022"; }; external-bus { ethernet@0,0 { compatible = "smc,smc91c111"; }; i2c@1,0 { compatible = "acme,a1234-i2c-bus"; rtc@58 { compatible = "maxim,ds1338"; }; }; flash@2,0 { compatible = "samsung,k8f1315ebm", "cfi-flash"; }; }; };
-
cpu编址
#address-cells = <1>; #size-cells = <0>;
-
表示用一个32位的数字去描述地址
-
首地址是一个32字节
地址长度是0
-
因为是cpu所以要求地址分别为0和1,是一个单独的地址
... serial@101f0000 { compatible = "arm,pl011"; reg = <0x101f0000 0x1000 >; }; serial@101f2000 { compatible = "arm,pl011"; reg = <0x101f2000 0x1000 >; }; gpio@101f3000 { compatible = "arm,pl061"; reg = <0x101f3000 0x1000 0x101f4000 0x0010>; }; interrupt-controller@10140000 { compatible = "arm,pl190"; reg = <0x10140000 0x1000 >; }; spi@10115000 { compatible = "arm,pl022"; reg = <0x10115000 0x1000 >; }; ... };
外总线中用了两个cell,一个用于片选一个用于地址的偏移
比如之前做的网卡移植
-
-
没有映射到总线上的设备,cpu不能直接访问,而是由父设备代替访问
比如i2c
i2c@1,0 { compatible = "acme,a1234-i2c-bus"; #address-cells = <1>; #size-cells = <0>; reg = <1 0 0x1000>; rtc@58 { compatible = "maxim,ds1338"; reg = <58>; }; };
-
非根节点的节点没有使用cpu地址线。需要一个range属性进行地址转换
ranges = <0 0 0x10100000 0x10000 // Chipselect 1, Ethernet
1 0 0x10160000 0x10000 // Chipselect 2, i2c controller
2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash
设备名称,
片选0 偏移量 0 映射地址范围 A -B
-
设备树的中断
- 板子上的任何设备都可以发起中断,地址的编址由设备树自然表示,而中断是独立于设备树节点之间的链接
属性名称 作用 备注 interrupt-controller 为节点说明它可以接受中断 #interrupt-cells 中断控制器的节点属性,类似于cell那两个 interrupt-parent 包含一个指向该设备链接的中断控制器的phandle phandle:可以理解为一个指针,这个指针指向这个节点,跨文件的节点的定义 interrupts 包含一个中断指示符列表,对应于相应的输出中断 中断指示符是一个或者多个cell的数据
全部加中断
/ {
compatible = "acme,coyotes-revenge";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
};
cpu@1 {
compatible = "arm,cortex-a9";
reg = <1>;
};
};
- cpu部分,这里只有标签位置加一个说明,指向中断控制器
serial@101f0000 {
compatible = "arm,pl011";
reg = <0x101f0000 0x1000 >;
interrupts = < 1 0 >;
};
serial@101f2000 {
compatible = "arm,pl011";
reg = <0x101f2000 0x1000 >;
interrupts = < 2 0 >;
};
- 串口的部分,标签和call一样
intc: interrupt-controller@10140000 {
compatible = "arm,pl190";
reg = <0x10140000 0x1000 >;
interrupt-controller;
#interrupt-cells = <2>;
};
- 这里标记了中断控制器的标签“inc”和对应的地址
- inc用于给根节点的interrupt-parent属性分配phandle
- 每个设备使用interrupts属性来接入不同的中断输入线
设备树的特殊节点
-
设备树的根节点"/"下面有两个特殊的子节点
aliases
chosen
aliases
aliases {
can0 = &flexcan1;
can1 = &flexcan2;
ethernet0 = &fec1;
ethernet1 = &fec2;
gpio0 = &gpio1;
gpio1 = &gpio2;
gpio2 = &gpio3;
gpio3 = &gpio4;
......
spi1 = &ecspi2;
spi2 = &ecspi3;
spi3 = &ecspi4;
usbphy0 = &usbphy1;
usbphy1 = &usbphy2;
};
- 对每个节点进行重新命名,为了方便访问节点
chosen子节点
- 辅助uboot向linux内核传递数据,一些bootargs参数