本章介绍Linux设备树(Device Tree)的起源、结构和因为设备树而引起的驱动和BSP变更。
18.1节阐明了ARM Linux为什么要采用设备树。
18.2节详细剖析了设备树的结构、节点和属性,设备树的编译方法以及如何用设备树来描述板上的设备、设备的地址、设备的中断号、时钟等信息。
18.3节讲解了采用设备树后,BSP和驱动的代码需要怎么改,哪些地方变了。
18.4节补充了一些与设备树相关的API定义以及用法。
本章内容是步入Linux 3.x时代后,嵌入式Linux工程师必备的知识体系。
18.1 ARM设备树起源
在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,很多代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。
设备树是一种描述硬件的数据结构,它起源于OpenFirmware(OF)。在Linux 2.6中,ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx中,采用设备树后,许多硬件的细节可以直接通过它传递给Linux,而不再需要在内核中进行大量的冗余编码。
设备树由一系列被命名的节点(Node)和属性(Property)组成,而节点本身可包含子节点。所谓属性,其实就是成对出现的名称和值。在设备树中,可描述的信息包括(原先这些信息大多被硬编码在内核中):
CPU的数量和类别。
内存基地址和大小。
总线和桥。
外设连接。
中断控制器和中断使用情况。
GPIO控制器和GPIO使用情况。
时钟控制器和时钟使用情况。
设备树基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader(U-boot)会将这棵树传递给内核,然后内核可以识别这棵树,并根据设备树展开出Linux内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ(中断)等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备。