什么是Linux的设备树

2019-11-20 08:36发布


设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等,如图所示:

b6ad7f71fe5b4497b726d9d4de7c48d3.jpg

设备树结构示意图

在图中,树的主干就是系统总线,IIC 控制器、GPIO 控制器、SPI 控制器等都是接到系统主线上的分支。IIC 控制器有分为IIC1 和IIC2 两种,其中 IIC1 上接了FT5206 和 AT24C02这两个 IIC 设备,IIC2 上值接了 MPU6050 这个设备。DTS 文件的主要功能就是按照图 43.1.1所示的结构来描述板子上的设备信息,DTS 文件描述设备信息是有相应的语法规则要求的,稍后我们会详细的讲解 DTS 语法规则。

在 3.x 版本(具体哪个版本笔者也无从考证)以前的 Linux 内核中ARM 架构并没有采用设备树。在没有设备树的时候 Linux 是如何描述 ARM 架构中的板级信息呢?在 Linux 内核源码中大量的 arch/arm/mach-xxx 和 arch/arm/plat-xxx 文件夹,这些文件夹里面的文件就是对应平台下的板级信息。比如在 arch/arm/mach-smdk2440.c 中有如下内容(有缩减):

90  static struct s3c2410fb_display smdk2440_lcd_cfg   initdata = {

91

92     .lcdcon5   = S3C2410_LCDCON5_FRM565 |

93             S3C2410_LCDCON5_INVVLINE |

94             S3C2410_LCDCON5_INVVFRAME |

95             S3C2410_LCDCON5_PWREN |

96             S3C2410_LCDCON5_HWSWP,

......

113 };

114
115 static struct s3c2410fb_mach_info smdk2440_fb_info   initdata = {

116    .displays   = &smdk2440_lcd_cfg,

117    .num_displays   = 1,

118    .default_display = 0,

......

133 };

134

135 static struct platform_device *smdk2440_devices[]   initdata = {

136    &s3c_device_ohci,

137    &s3c_device_lcd,

138    &s3c_device_wdt,

139    &s3c_device_i2c0,

140    &s3c_device_iis,

141 };

上述代码中的结构体变量 smdk2440_fb_info 就是描述 SMDK2440 这个开发板上的 LCD 信息的,结构体指针数组 smdk2440_devices 描述的 SMDK2440 这个开发板上的所以平台相关信息。这个仅仅是使用 2440 这个芯片的 SMDK2440 开发板下的 LCD 信息,SMDK2440 开发板还有很多的其他外设硬件和平台硬件信息。使用 2440 这个芯片的板子有很多,每个板子都有描述相应板级信息的文件,这仅仅只是一个 2440。随着智能手机的发展,每年新出的ARM 架构芯片少说都在数十、数百款,Linux 内核下板级信息文件将会成指数级增长!这些板级信息文件都是.c 或.h 文件,都会被硬编码进Linux 内核中,导致Linux 内核“虚胖”。就好比你喜欢吃自助餐,然后花了 100 多到一家宣传看着很不错的自助餐厅,结果你想吃的牛排、海鲜、烤肉基本没多少,全都是一些凉菜、炒面、西瓜、饮料等小吃,相信你此时肯定会脱口而出一句“F*k!”、“骗子!”。同样的,当 Linux 之父 linus 看到 ARM 社区向Linux 内核添加了大量“无用”、冗余的板级信息文件,不禁的发出了一句“This whole ARM thing is a f*cking pain in the ass”。从此以后 ARM 社区就引入了 PowerPC 等架构已经采用的设备树(Flattened Device Tree),将这些描述板级硬件信息的内容都从 Linux 内中分离开来,用一个专属的文件格式来描述,这个专属的文件就叫做设备树,文件扩展名为.dts。一个 SOC 可以作出很多不同的板子,这些不同的板子肯定是有共同的信息,将这些共同的信息提取出来作为一个通用的文件,其他的.dts 文件直接引用这个通用文件即可,这个通用文件就是.dtsi 文件,类似于 C 语言中的头文件。一般.dts 描述板级信息(也就是开发板上有哪些 IIC 设备、SPI 设备等),.dtsi 描述 SOC 级信息(也就是SOC 有几个CPU、主频是多少、各个外设控制器信息等)。

这个就是设备树的由来,简而言之就是,Linux 内核中 ARM 架构下有太多的冗余的垃圾板级信息文件,导致Linus 震怒,然后ARM 社区引入了设备树。