Linux设备树device-tree完全解析
1. Linux中说的设备树是什么?
对于搞Linux驱动开发和BSP的工程师来说,总是不可避免的接触到设备树,那么设备树指的是什么呢?其实通常所说的设备树是指Linux内核里面的设备树文件,以.dts结尾,也叫做设备树源文件,这个文件可以通过一个叫dtc的程序把他编译成.dtb文件,编译后的文件就是Linux启动时需要的设备树描述文件,Linux启动的时候会解析它然后根据里面的设备树内容决定初始化哪些硬件模块。
官方定义
The “Open Firmware Device Tree”, or simply Device Tree (DT), is a data structure and language for describing hardware.
设备树是一种数据结构和一种用于描述硬件信息的语言。
2. 那么,设备树从哪里来的,到底怎么用?
设备树怎么用,网上有一大把教程,那他从哪里来的,为什么产生呢?
设备树是从Linux内核在2.6版本引入的,引入的背景是为了以标准的模式来描述SOC上的设备信息以及相关联的设备信息。
3. 设备树文件描述哪些设备?
设备树主要描述2部分内容
第一部分时soc信息,也就是soc内部的硬件资源,这部分资源以soc的计算资源cpu为核心,然后时soc内部总线外挂的时钟/内存/中断控制器/DMA控制器,接下来就是用于连接外部设备的控制器,比如 GPIO控制器/PWM ADC控制器/串口 SPI I2C USB 以太网等控制器 /显示设备控制器 音频设备控制器等等
第二部分就是上面的外设控制器挂载的外部设备,比如音频控制器挂载的CODEC芯片,串口和I2C挂载的各种外部传感器执行器,蓝牙wifi模块等等。
以上的每一种设备,在内核中都会对应一种驱动,这个驱动加载与否以及加载时使用的参数就是设备树描述的内容。
4. 设备树的使用流程
4.1 根据soc和挂载的外设,编辑.dts 文件
arm的文件目录是在 linux/arch/arm/boot/dts/... 下面
编辑好之后,在编译内核的时候会生成一个dtb文件。
4.2 将dtb文件烧录到启动介质,比如EMMC存储芯片的固定地址,对于服务器这类操作系统就是/boot目录下面,boot工具启动内核的时候,会把这个文件加载到内存中,并且把内存地址告诉内核,内核就可以读到dtb文件了。
4.3 内核对dtb文件的解析
内核在启动的时候,会通过unflatten_device_tree() 设备树解析核心函数来解析dtb文件,他的子函数unflatten_dt_node()会把我们描述的每一个是被解析为1个 device_node结构体,最终所有的 device_node被存储到全局变量 of_allnodes 中。
4.4 内核将 device_node of_allnodes中的soc控制器设备转化为平台设备 platform_device 挂载到平台总线上
内核启动执行完4.3之后,会通过 of_platform_populate() 平台设备迁移函数将 of_allnodes 中的设备节点迁移为平台设备,供平台驱动的初始化使用,因为了解平台驱动的人都知道,该驱动使用 platform_device 读取里面的初始化参数来完成初始化,不能直接使用 device_node,当然平台驱动外的外设驱动可以通过device_node来获取初始化参数。
4.3和4.4的代码都放在 linux/driver/of/ 目录下面,具体调用流程和代码执行逻辑参考 设备树解析代码的调用与执行