设备树说明
以s5p6818为例
编译命令
将dts文件编译为dtb:
dtc -I dts -O dtb xxx.dtb xxx.dts
将dtb文件反编译为dts:
dtc -I dtb -O dts xxx.dts xxx.dtb
各节点属性说明
cpu节点
/ {
model = "nexell soc";
compatible = "nexell,s5p6818";
#address-cells = <0x1>;
#size-cells = <0x1>;
cpus {
#address-cells = <0x2>;
#size-cells = <0x0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0 0x0>;
enable-method = "psci";
cpu-release-addr = < 0x1 0xc0010230 >;
#cooling-cells = <2>;
cpu-idle-states =<&CPU_SLEEP>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a53";
reg = <0x0 0x1>;
enable-method = "psci";
cpu-release-addr = < 0x1 0xc0010230 >;
cpu-idle-states =<&CPU_SLEEP>;
};
};
};
/:表示根节点
compatible = “nexell,s5p6818”;
compatible: “兼容性” 属性,这是非常重要的一个属性兼容属性,由该属性值来匹配对应的驱动代码。
“nexell,s5p6818”:该值遵循"manufacturer,model"格式manufacturer表示芯片厂商,model表示驱动名称
compatible是一个字符串列表。列表中的第一个字符串指定节点在表单中表示的确切设备","。
寻址相关属性 address-cells size-cells reg
soc {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
reg = <0xc0000000 0x300000>;
interrupt-parent = <&gic>;
ranges;
};
#address-cells
:表示reg属性中表示地址字段的单元个数,每个单元32bit,即用多少个32bit单元表示地址信息。
#size-cells
:表示reg属性中表示长度字段的单元个数,每个单元32bit,即用多少个32bit单元表示长度信息。
reg
:该属性一般用于描述设备地址空间资源信息,一般都是某个外设的寄存器地址范围信息。其式为reg = <address1 length1 [address2 length2] [address3 length3] … >。每个地址值都是一个或多个 32 位整数的列表,称为单元格。同样,长度值可以是单元格列表,也可以是空的。
上面的 #address-cells = <1>; #size-cells = <1>;
其#address-cells=1表示reg属性中描述地址字段需要1个32bit单元,#size-cells=1表示reg属性中描述长度字段需要2个单元,即reg = <0xc0000000 0x300000>
0xc000000:表示控制器起始地址
0x300000:表示控制器所占用的大小
根节点与根节点的直接子节点,都使用了CPU的地址分配空间,但是根节点的非直接子节点,并不会自动使用CPU的地址空间,因此需要手动用属性分配。
中断相关节点属性 interrupt-controller、interrupt-cells、interrupt-parent、interrupts
中断控制器
对于中断控制器结点,它提供如下属性:
interrupt-controller
表明自己的身份为中断控制器
interrupt-cells
属性与#address-cells属性相似,它声明了设备结点interrupt cells的个数。对于ARM GIC中断控制器而言 #interrupt-cells = <3>
interrupt-parent
指定设备结点所依附的中断控制器,当结点没有指定interrupt-parent时,则从父结点继承
interrupts
指定设备结点的中断号和触发方式,该属性cell个数,由它依附的中断控制器#interrupt-cells决定,另外某些设备还可以使用多个中断号
gic:interrupt-controller@c0009000 {
compatible = "arm,gic-400";
interrupt-controller;//表明自己的身份为中断控制器
#interrupt-cells = <3>;//声明了设备结点interrupt cells的个数
reg = <0xC0009000 0x1000>, <0xC000a000 0x100>;
};
pmu {
compatible = "arm,armv8-pmuv3";
interrupt-parent = <&gic>;//设备结点所依附的中断控制器,当结点没有指定interrupt-parent时,则从父结点继承
interrupts = <0 IRQ_P0_PMUIRQ0 0>,//指定设备结点的中断号和触发方式,该属性cell个数,由它依附的中断控制器#interrupt-cells决定
<0 IRQ_P0_PMUIRQ1 0>,
<0 IRQ_P0_PMUIRQ2 0>,
<0 IRQ_P0_PMUIRQ3 0>,
<0 IRQ_P1_PMUIRQ0 0>,
<0 IRQ_P1_PMUIRQ1 0>,
<0 IRQ_P1_PMUIRQ2 0>,
<0 IRQ_P1_PMUIRQ3 0>;
interrupt-affinity = <&cpu0>,
<&cpu1>,
<&cpu2>,
<&cpu3>,
<&cpu4>,
<&cpu5>,
<&cpu6>,
<&cpu7>;
};
具体含义如下:
第一个cell表示中断类型
,0代表SPI interrupts,1代表PPI interrupts
第二个cell表示中断号码
,SPI interrupts的中断号范围是0 ~ 987,而PPI interrupts的中断号范围是0 ~ 15
第三个cell表示中断触发方式
,它有4个值,分别为1,2,4,8
1表示上升沿触发
2表示下降沿触发
4表示高电平触发
8表示低电平触发
gpio控制器属性 gpio-cells
pinctrl@C0010000 {
gpio_b: gpiob {
gpio-controller;//说明该节点为gpio控制器
#gpio-cells = <2>;//该属性与#address-cells相似,它声明了设备结点gpio cells的个数
interrupt-controller;
#interrupt-cells = <2>;
};
};
leds: gpio-leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 =<&led1_gpio>;
led@1 {
gpios = <&gpio_b 12 GPIO_ACTIVE_LOW>;//由gpio-cells决定个数,第一个cell表示gpio号,第二个cell表示gpio有效电平,gpio为 32*1+12=44
label = "status_led";
linux,default-trigger = "heartbeat";
linux,default-trigger-delay-ms = <0>;
};
};
gpio-cells
该属性与#address-cells相似,它声明了设备结点gpio cells的个数
一般gpio控制器#gpio-cells = <2>
第一个cell表示gpio号,第二个cell表示gpio有效电平
其他属性 aliases、chosen
aliases
:别名属性,使用方式:property = &label;
chosen
:该属性并不表示一个真实的设备,但是提供一个空间,用于传输固件和Linux之间的数据,像启动参数,
aliases {
ethernet0 = ð0;
serial0 = &serial0;
};
chosen {
bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};
查看设备树信息
ls /proc/device-tree/
或
ls /sys/firmware/devicetree/base
/proc/device-tree 是链接文件, 指向 /sys/firmware/devicetree/base
查看原始的dtb文件:
hexdump -C /sys/firmware/fdt
查看所有硬件信息:
ls /sys/devices/platform
系统中所有的platform_device, 有来自设备树的, 也有来有.c文件中注册的