前边讲解了内核编译选项的配置,这一节我们详细讲一下设备树。设备树的知识是Linux驱动开发人员必备的技能,我们现在使用的Linux内核,绝大多数都是支持设备树功能的,掌握设备树是软件嵌入式工程师必备的一项技能。
设备树的起源
设备树(Device Tree)是一种描述硬件资源的数据结构,它由uboot传递给Linux内核,被内核解析,内核根据设备树中的硬件描述信息加载利用相应驱动资源。在引入设备树之前,Linux内核中充斥着大量的用于描述板级硬件信息的文件,拥有不同硬件资源的板卡 ,都有其对应的板级文件或者冗余文件,随着Linux内核支持的板卡越来越多,板级文件也越来越多。尤其是一些冗余的文件信息导致了内核的臃肿,为了解决这一问题Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a fucking pain in the ass”,因此,ARM Linux社区作出了回应,引入了设备树Device Tree,这样一来许多硬件的细节可以直接透过设备树传递给Linux内核,而不再需要在内核中进行大量的冗余编码来适配不同的板卡。
设备树组成和结构及dts、dtb、dtsi
设备树Device Tree由一系列被命名的节点(node)和属性(property)组成,而节点本身可包含子节点。所谓属性,其实就是成对出现的name和value。在设备树中,可描述的信息包括:
一、CPU的数量和类别;
二、内存基地址和大小;
三、总线和桥;
四、外设连接;
五、中断控制器和中断使用情况;
六、GPIO控制器和GPIO使用情况;
七、Clock控制器和Clock使用情况;
这种以树状节点的方式描述一个设备的各种硬件信息:CPU、GPIO、时钟、中断、内存等,形成类似文本文件,很好的解决了这些问题。
它基本上就是画一棵电路板上CPU、总线、设备组成的树,uboot在启动的时候会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备。
通常由.dts文件以文本方式对系统设备树进行描述,经过Device Tree Compiler(dtc)将dts文件转换成二进制文件binary device tree blob(dtb),.dtb文件可由Linux内核解析,有了device tree就可以在不改动Linux内核的情况下,对不同的平台实现无差异的支持,硬件有变动时不需要重新编译内核或驱动程序,只需更换相应的dts文件即可。dtsi文件被dts文件包含引用,这类似于C语言C文件include包含.h文件,对于同一个节点的设置情况,dts中的配置会覆盖dtsi中的配置。