1、设备点属性回顾
前面根节点“/”的cpus子节点下面又包含两个cpu子节点,描述了此设备上的两个CPU,并且两者的兼容属性为:“arm,cortex-a9”。
注意cpus和cpus的两个cpu子节点的命名,它们遵循的组织形式为[@],<>中的内容是必选项,[]中的则为可选项。
name是一个ASCII字符串,用于描述节点对应的设备类型,如3com Ethernet适配器对应的节点name宜为ethernet,而不是3com509。
如果一个节点描述的设备有地址,则应该给出@unit-address。多个相同类型设备节点的name可以一样,只要unit-address不同即可,如本例中含有cpu@0、cpu@1以及serial@101f0000与serial@101f2000这样的同名节点。设备的unit-address地址也经常在其对应节点的reg属性中给出。
**对于挂在内存空间的设备而言,@字符后跟的一般就是该设备在内存空间的基地址,**譬如arch/arm/boot/dts/exynos4210.dtsi中存在的:
sysram@02020000 { compatible = "mmio-sram"; reg = <0x02020000 0x20000>; … }
上述节点的reg属性的开始位置与@后面的地址一样。
对于挂在I2C总线上的外设而言,@后面一般跟的是从设备的I2C地址,譬如arch/arm/boot/dts/exynos4210-trats.dts中的mms114-touchscreen:
i2c@13890000 { … mms114-touchscreen@48 { compatible = "melfas,mms114"; reg = <0x48>; … }; };
具体的节点命名规范可见ePAPR(embedded Power Architecture Platform Reference)标准,在https://www.power.org中可下载该标准。
2、设备添加label
我们还可以给一个设备节点添加label,之后可以通过&label的形式访问这个label,这种引用是通过phandle(pointer handle)进行的。
例如,在arch/arm/boot/dts/omap5.dtsi中,第3组GPIO有gpio3这个label,如代码清单18.12所示。
1 gpio3: gpio@48057000 { 2 compatible = "ti,omap4-gpio"; 3 reg = <0x48057000 0x200>; 4 interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; 5 ti,hwmods = "gpio3"; 6 gpio-controller; 7 #gpio-cells = <2>; 8 interrupt-controller; 9 #interrupt-cells = <2>; 10 };
而hsusb2_phy这个USB的PHY复位GPIO用的是这组GPIO中的一个,所以它通过phandle引用了“gpio3”,如代码清单18.13所示。
1 /* HS USB Host PHY on PORT 2 */ 2 hsusb2_phy: hsusb2_phy { 3 compatible = "usb-nop-xceiv"; 4 reset-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; /* gpio3_76 HUB_RESET */ 5 };
代码的第1行的gpio3是gpio@48057000节点的label,而代码清单18.13的hsusb2_phy则通过&gpio3引用了这个节点,表明自己要使用这一组GPIO中的第12个GPIO。很显然,这种phandle引用其实表明硬件之间的一种关联性(这不就是汇编的函数,然后调函数。)
再举一例,在arch/arm/boot/dts/omap5.dtsi中,我们可以看到类似如下的label,从这些实例可以看出,label习惯以<设备类型>进行命名:
i2c1: i2c@48070000 { } i2c2: i2c@48072000 { } i2c3: i2c@48060000 { }…
读者也许发现了一个奇怪的现象,就是代码清单18.13中居然引用了GPIO_ACTIVE_LOW这个类似C语言的宏。文件.dts的编译过程确实支持C的预处理,相应的.dts文件也包括了包含GPIO_ACTIVE_LOW这个宏定义的头文件:
#include <dt-bindings/gpio/gpio.h>
对于ARM而言,dt-bindings头文件位于内核的arch/arm/boot/dts/include/dt-bindings目录中。观察该目录的属性,它实际上是一个符号链接:
baohua@baohua-VirtualBox:~/develop/linux/arch/arm/boot/dts/include$ ls -l dt- bindings lrwxrwxrwx 1 baohua baohua 34 11月 28 00:16 dt-bindings -> ../../../../../ include/dt-bindings
从内核的scripts/Makefile.lib这个文件可以看出,文件.dts的编译过程确实是支持C预处理的。
cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \ -i $(dir $<) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
怎么看出来的?
是因为它是先做了
$(CPP)$(dtc_cpp_flags)-x assembler-with-cpp-o$(dtc-tmp)$<
再做的.dtc编译。
先链接好了,才编译.dtc的。