编译ZedBoard的devicetree.dtb
设备树是一种用来描述硬件的数据结构,它可以描述CPU,可以描述时钟、中断控制器、IO控制器、SPI总线控制器、I2C控制器、存储设备等任何现有驱动设备。内核可以识别这棵树,并根据它展开出Linux 内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源,也被传递给了内核, 内核会将这些资源绑定给展开的相应的设备。
ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx,采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。
设备树的编译器在linux源码目录下scripts/dtc/中。注意:要使用设备树,内核在编译时需要配置为打开设备树编译器。
生成设备树有两种方法:一种是通过linux源码中的设备树源文件生成设备树、另一种是使用xilinx的SDK2014.2软件生成设备树。
方法一:
1、在linux源码目录下的arch/arm/boot/dts目录中有设备树源文件,ZedBoard对应的设备树源文件名为zynq-zed.dts(如果需要包含PL部分的借口,则需要手动在zynq-zed.dts中添加相应的设备描述)
2、编译设备树:在linux源码根目录下运行如下命令,即可生成devicetree.dtb文件。
scripts/dtc/dtc –I dts –O dtb –o devicetree.dtb arch/arm/boot/dts/zynq-zed.dts
注:dtb的反编译命令:
scripts/dtc/dtc –I dtb –O dts –o my_devicetree.dts devicetree.dtb
方法二:
由于从2014.1版本开始,SDK里面软硬件管理的机制发生了变化,无法在2014.1上生成DTS文件。为了解决这个问题,xilinx在2014.2版本的SDK里面提供了一个新的BSP包。为了和之前的版本隔离开,下载位置也发生了变化:https://github.com/Xilinx/device-tree-xlnx/releases
将2014.2对应的gz文件下载下来,解压后发现和以前相比变化非常大:
下面是2013.4的SDK生成devicetree的BSP包解压后的内容
而2014.2版本的SDK生成devicetree的BSP包解压后的内容如下:
随便进入其中一个目录查看文件夹内容: 在2014.2的版本里面将每个接口放到独立的文件夹去描述了。
之前制作dts的步骤我们可以参考http://www.wiki.xilinx.com/Build+Device+Tree+Blob。在2014.2版本里面也是参考该链接的步骤来做。
将下载的文件device-tree-xlnx-xilinx-v2014.2.tar.gz解压得到一个叫device-tree-xlnx-xilinx-v2014.2目录,将该目录下同样名为device-tree-xlnx-xilinx-v2014.2的目录重命名为device-tree_v0_00_a,然后将device-tree_v0_00_a拷贝到一个名叫bsp的目录中,bsp的上一级目录的路径将会是添加到repo中的路径。
比如我的device-tree_v0_00_a文件夹的路径是D:\Xilinx-doc\Code\targz_devicetree\devicetree_repo\bsp,其中D:\Xilinx-doc\Code\targz_devicetree\devicetree_repo就是被添加到repo中的路径:
添加完了repo路径之后,通过file->New->Board Support Package来创建DTS的BSP:
在弹出的界面中选择device tree
然后点击Finish按钮:
这里可以直接先点击OK,当然也可以添加自己的bootargs,如果你的硬件工程里面有多个串口,可能还要配置一下console_device,也就是linux启动后的打印串口。
点击OK之后,在工程窗口会生成一个device_tree_bsp_0的目录,这个目录里面有ps.dtsi和system.dts两个文件是我们需要的。
其中ps.dtsi包含了你外设接口信息的内容,但它不是一个完整的DTS,后缀中的i表示它类似于C语言里面的头文件。在system.dts里面通过/include/ "ps.dtsi"来包含它。
system.dts里面的内容比较简单,值有chosen、aliases以及memory的信息:
/*
* CAUTION: This file is automatically generated by Xilinx.
* Version:
* Today is: Mon Jul 07 16:24:07 2014
*/
/dts-v1/;
/include/ "ps.dtsi"
/{
chosen {
bootargs = "console=ttyPS0,115200";
linux,stdout-path = &ps7_uart_1;
} ;
aliases {
ethernet0 = &ps7_ethernet_0;
serial0 = &ps7_uart_1;
spi0 = &ps7_qspi_0;
} ;
ps7_ddr_0: [email protected] {
device_type = "memory";
reg = <0x0 0x20000000>;
} ;
};
如果硬件工程里面包含了PL的接口怎么办?事实上如果你的硬件工程里面有PL的信息的话,会另外生成一个pl.dtsi的文件。
将ps.dtsi和system.dts文件拷贝到虚拟机里面,你可以考虑放到2014.2的内核arch/arm/boot/dts目录中,也可以放到别的地方。
如果你将上述两个文件放到arch/arm/boot/dts目录中,在linux的目录里面直接make system.dtb就可以生成dtb文件。
如果你放到别的目录,也可以在对应目录执行dtc -I dts -O dtb -o system.dtb system.dts生成dtb文件。
需要特别指出的一点是,SDK里面生成的ps.dtsi文件里面会将ZYNQ所有的接口都加进去,比如说你没有选择UART0,在ps.dtsi里面也会有UART0的信息:
ps7_uart_0: [email protected] {
clock-names = "ref_clk", "aper_clk";
clocks = <&clkc 23>, <&clkc 40>;
compatible = "xlnx,ps7-uart-1.00.a";
interrupt-parent = <&ps7_scugic_0>;
interrupts = <0 27 4>;
reg = <0xE0000000 0x1000>;
status = "disabled";
} ;
但是与你硬件工程中包括的接口相比,在这种不存在的接口的描述信息里面有一个status = “disabled”字段,用户可以根据这个字段将不需要的接口删除。