您的位置:首页 > 运维架构 > Linux

ARM Linux设备树

2016-04-03 11:04 316 查看
ARM设备树起源

在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,很多代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。

设备树是一种描述硬件的数据结构,它起源于OpenFirmware(OF)。在Linux2.6中,ARM架构的板级硬件细节过多的被编码在arch/arm/plat-xxx和arch/arm/mach-xxx中,采用设备树后,许多硬件的细节可以直接通过它传递给Linux,而不再需要在内核中进行大量的冗余编码。

设备树由一系列被命名的节点(Node)和属性(Property)组成,而节点本身可包含子节点。所谓属性,其实就是成对出现的名称和值。在设备树中,可描述的信息包括:

CPU的数量和类型

内存的基地址和大小

总线和桥

外设连接

中断控制器和中断使用情况

GPIO控制器和GPIO使用情况

时钟控制器和时钟使用情况

它基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device、i2c_client、spi_device等设备,和这些设备用到的内存、IRQ资源等。

内核中的dts存放位置:



由于一个SOC可能对于多个产品和电路板,势必包含许多公共部分,一般公共的部分就提炼为.dtsi,类似C语音的头文件。其他dts就包含这个dtsi。

如:

/include/ "skeleton.dtsi"


DTC(Device Tree Compiler)

DTC是.dts编译为.dtb的工具。源码位于scripts/dtc。

在ubuntu中可以安装dtc,命令如下:

sudo apt-get install device-tree-compiler


在arch/arm/boot/dts/Makefile中,描述了当哪种SoC被选中后,哪些.dtb文件会被编译出来,如下:

vi arch/arm/boot/dts/Makefile
531 dtb-$(CONFIG_ARCH_S3C24XX) += \
532         s3c2416-smdk2416.dtb \
533         s3c2440-tq2440.dtb


DTC除了可以编译.dts外,其实也可以反汇编.dtb。命令如下:

dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/s3c2440-tq2440.dtb


DTB

是.dts编译后的二进制格式,可以由Linux内核解析,U-Boot也可以解析。

通常在我们为电路板制作NAND、SD启动镜像时,会为.dtb文件单独留下一个很小的区域以存放dtb,之后uboot会读取此区域到内存中,在把地址传递给kernel,启动kernel。

Linux内核也支持一种变通的模式,可不把.dtb文件单独存放,而是直接和zImage绑定一起做成一个镜像,类似cat zImage xxx.dtb >zImage_with_dtb的效果。当然内核编译的时候要使能CONFIG_ARM_APPEND_DTB这个选项,以支持”Use appended device tree blob to zImage”。

关于设备描述怎么写,可以参考文档:Documentation/devicetree/bindings/

设备树绑定文档里面有:

关于该模块最基本的描述

必须属性的描述

可选属性的描述

一个示例

U-Boot从v1.1.3开始支持设备树,为了在uboot里使能,需要在include/configs/tq2440.h中添加:

#define CONFIG_OF_LIBFDT


在uboot中可从nand、sd或tftp等介质将.dtb读入内存,假设.dtb放到内存地址为0x30000000,之后可在uboot命令行运行:

<tq2440>fdt addr 0x30000000


fdt的其他操作dts的命令就可以使用了,如fdt resize、fdt print等。

在boot中可以用如下命令来启动内核:

<tq2440>bootz kernel_addr initrd_address dtb_address


kernel_addr是uboot把内核加载到内存的地址

initrd_address是ramdisk的内存地址,如果不存在,则使用”-“代替

最后一个是dtb在内存中的地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内核 linux