移植DTS时,首先要利用SDK,生成对应版本的kernel的DTS。
SDK生成DTS,主要依据的HDF文件。
需要从HDF中提取出有哪些外设,以及这些外设对应的REG。
SDK是根据HDF文件生成的DTS,所以这个生成的DTS,是参考的基础,
它决定了有哪些硬件资源需要被开启,并生成设备节点。
以2017.4版本的kernel为例。生成我们的板子system-top.dts,并和zynq-zed.dts进行比较。
从
https://github.com/Xilinx/linux-xlnx/releases
下载linux-xlnx源码。
经过比较,我们发现,skeleton.dtsi和zynq-7000.dtsi两个文件的内容,是完全一样的。
不一样的是,zynq-zed.dts和pcw.dts+system-top.dts
1)chosen->bootargs。内核默认是空字符串。我们在SDK的BSP中设置了这个字符串。
2)/->compatible。内核在zed.dts中,覆盖了zynq-7000.dtsi中的定义,添加了zynq-zed的匹配字。SDK的BSP中,未覆盖。所以仅仅匹配zynq-7000.dtsi中的定义。
3)clkc->fclk-enable。SDKBSP中,覆盖了zynq-7000.dtsi中的定义。zed.dts中未覆盖。这取决于是否使用FCLK。
4)uart1->status,SDKBSP中,覆盖了zynq-7000.dtsi中的定义。zed.dts中也覆盖了zynq-7000.dtsi中的定义。这取决于是否开启该设备节点,以及以什么模式使用该设备节点。
5)intc->num_cpus,SDKBSP中,覆盖了zynq-7000.dtsi中的定义。zed.dts中未覆盖。这取决于是否如何调度CPUS。
6)intc-> num_interrupts,SDK BSP中,覆盖了zynq-7000.dtsi中的定义。zed.dts中未覆盖。这取决于监测哪个中断号。
以下是zed.dts中有但是system-top.dts中没有的。也就是说,我们的板子没有用到这些硬件资源,但是zedboard用到了。
1)usb_phy0。定义了一个USBPHY0节点。
2)usb0。开启了一个USBC控制器。覆盖了zynq-7000.dtsi中的某些定义。添加了某些定义。
3)sdhci0。开启了一个SD卡控制器。覆盖了zynq-7000.dtsi中的某些定义。添加了某些定义。
4)gem0。开启了一个ETH控制器。覆盖了zynq-7000.dtsi中的某些定义。添加了某些定义。
5)qspi。开启了一个QSPI控制器。覆盖了zynq-7000.dtsi中的某些定义。添加了某些定义。
可见,zynq-7000.dtsi对ZYNQ的片上PS侧的外设资源做总体定义。
而zynq-zed.dts对ZYNQ的片外资源做定义,另外,对片上PS侧的外设资源做补充定义或者覆盖定义。
最好先在SDK中生成DTS,然后根据生成的DTS的内容,再来修改生成所需的内核DTS。
我们以2017.4中的zynq-7000.dtsi为基础,分析HDF和DTS的关系。
以下是系统资源,使用了PS侧就必须使用的硬件资源。
(1)intc
reg = <0xF8F01000 0x1000>,
<0xF8F00100 0x100>;
HDF里,分别对应ps7_intc_dist_0,ps7_scugic_dist_0;
(2)scutimer
reg = <0xf8f00600 0x20>;
HDF里,对应ps7_scutimer_0
(3)slcr
reg = <0xF8000000 0x1000>;
HDF里,对应ps7_slcr_0
(3.1)clkc
reg = <0x100 0x100>;
由于clkc是slcr中的一部分,所以它是slcr的子节点。它的编址是相对于slcr的基地址的相对地址。这是子地址域的寻址。
(3.2)rstc
reg = <0x200 0x48>;
由于rstc是slcr中的一部分,所以它是slcr的子节点。它的编址是相对于slcr的基地址的相对地址。这是子地址域的寻址。
(3.3)pinctrl0
reg = <0x700 0x200>;
由于pinctrl0是slcr中的一部分,所以它是slcr的子节点。它的编址是相对于slcr的基地址的相对地址。这是子地址域的寻址。
(4)L2
reg = <0xF8F02000 0x1000>;
HDF中,对应ps7_l2cachec_0
(5) ocmc
reg = <0xf800c000 0x1000>;
HDF中,对应ps7_ocmc_0
(6)mc
reg = <0xf8006000 0x1000>;
HDF中,对应ps7_ddrc_0
(7) pmu
reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
HDF中,对应ps7_pmu_0
(8) adc
reg = <0xf8007100 0x20>;
HDF中,对应ps7_xadc_0
(9)dmac_s
reg = <0xf8003000 0x1000>;
HDF中,对应ps7_dmac_s
(10)devcfg
reg = <0xf8007000 0x100>;
HDF中,对应ps7_dev_cfg_0
(11)global_timer
reg = <0xf8f00200 0x20>;
HDF中,对应ps7_globaltimer_0
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
以下是虽然被定义但是未被开启的硬件资源(status = “disabled”;),这些资源未出现在HDF中。
(13)uart0
reg = <0xE0000000 0x1000>;
(14) can0
reg = <0xe0008000 0x1000>;
(15)can1
reg = <0xe0009000 0x1000>;
(16)i2c0
reg = <0xe0004000 0x1000>;
(17)i2c1
reg = <0xe0005000 0x1000>;
(18)spi0
reg = <0xe0006000 0x1000>;
(19)spi1
reg = <0xe0007000 0x1000>;
(20) smcc
reg = <0xe000e000 0x1000>;
(20.1) nand0
reg = <0xe1000000 0x1000000>;
是smcc的子节点。在子地址域中寻址。由于父节点设置了ranges;属性。所以是1:1映射。
(20.2)nor0
reg = <0xe2000000 0x2000000>;
是smcc的子节点。在子地址域中寻址。由于父节点设置了ranges;属性。所以是1:1映射。
(21)gem1
reg = <0xe000c000 0x1000>;
(22)sdhci1
reg = <0xe0101000 0x1000>;
( 23 ) usb1
reg = <0xe0003000 0x1000>;
(24) ttc0
reg = <0xF8001000 0x1000>;
(25)ttc1
reg = <0xF8002000 0x1000>;
(26)watchdog0
reg = <0xf8005000 0x1000>;
(27)efuse
reg = <0xf800d000 0x20>;
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
以下是PS侧支持的外设资源,如果status=“okay”,那就是被开启的。
(1)uart1
reg = <0xE0001000 0x1000>;
HDF中,对应ps7_uart_1
(2) qspi
reg = <0xe000d000 0x1000>;
(3)gem0
reg = <0xe000b000 0x1000>;
HDF中,对应
(4)sdhci0
reg = <0xe0100000 0x1000>;
HDF中,对应
( 5 ) usb0
reg = <0xe0002000 0x1000>;
HDF中,对应
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
所以,如果我们开启了某些硬件资源,可以仿照zed中的描述语句,将对应的设备节点开启即可。
再来看zynq-zed.dts。
(1) memory
reg = <0x0 0x20000000>;
HDF中,对应ps7_ram_0,ps7_ddr_0。
(2) usb_phy0
reg = <0xe0002000 0x1000>;
HDF中,对应
(3) flash
&qspi {
u-boot,dm-pre-reloc;
status = "okay";
is-dual = <0>;
num-cs = <1>;
flash@0 {
compatible = "n25q128a11";
reg = <0x0>;
spi-tx-bus-width = <1>;
spi-rx-bus-width = <4>;
spi-max-frequency = <50000000>;
#address-cells = <1>;
#size-cells = <1>;
partition@qspi-fsbl-uboot {
label = "qspi-fsbl-uboot";
reg = <0x0 0x100000>;
};
partition@qspi-linux {
label = "qspi-linux";
reg = <0x100000 0x500000>;
};
partition@qspi-device-tree {
label = "qspi-device-tree";
reg = <0x600000 0x20000>;
};
partition@qspi-rootfs {
label = "qspi-rootfs";
reg = <0x620000 0x5E0000>;
};
partition@qspi-bitstream {
label = "qspi-bitstream";
reg = <0xC00000 0x400000>;
};
};
};
由于QFLASH是挂载qspi总线上的,所以,flash是qspi的子节点。
在flash设备节点中,定义了flash的分区信息。
、、、、、、、、、、、、、、、、、、、、、、、
另外注意:
不同版本的kernel中的DTS,不能混用。
以2017.4和2014.3为例,同样的zedboard。
先来看zynq-7000.dtsi文件,
2017.4版本中,设备节点的硬件资源定义虽然一样,但是匹配字不一样,也就是说,驱动版本升级了。
另外,新增了一些属性项,这些属性项是新驱动要用到的。
而且由于新增加了一些驱动模块,所以也新增了对应的设备节点。
其中2017.4独有的设备节点如下。
1)/->amba->slcr->rstc。
2)/->amba->slcr->pinctrl0。
3)/->amba->efuse。
4)/->fpga_full。
再来看zynq-zed.dts:
2017.4版本中,设备节点的硬件资源定义虽然一样,但是匹配字不一样,也就是说,驱动版本升级了。
另外,新增了一些属性项,这些属性项是新驱动要用到的。
而且由于新增加了一些驱动模块,所以也新增了对应的设备节点。
2017.4独有的如下:
1)/->usb_phy0。
内核对USBPHY单独进行驱动。