内容发布更新时间 : 2024/12/23 1:40:35星期一 下面是文章的全部内容请认真阅读。
精心整理
1、ARMLinux社区为什么要引入设备树 Linux之父LinusTorvalds闲来无事,在翻看ARMLinux代码的时候,有一天终于忍不住了。他在2011年3月17日的ARMLinux邮件列表中说道:“ThiswholeARMthingisaf*ckingpainintheass”。这句话迫使ARMLinux社区引入了设备树。 LinusTorvalds为什么会发飙呢?而ARMLinux社区的牛人为什么又乖乖地听话了?你得首先理解Linux设备驱动框架中一个非常好的设计:设备信息和驱动分离。 为了说明设备信息和驱动分离的概念,这里用一个简单的模拟代码来解释: 【例-1】实现一个代码,把要使用的信息简单写死在代码中: intadd()/*模拟驱动代码*/ { return3+5;/*模拟设备信息*/ } 优点:简单 缺点:一旦加数和被加数发生变化就得改代码 改进设计如下: 【例-2】实现一个代码,把要使用的信息和操作代码分离开来: structdev{ intid; intx; inty; };/*模拟设备信息结构*/ strcutdrv{ intid; int(*add)(structdev*info); };/*模拟驱动结构*/ intadd(structdev*info)/*模拟驱动代码*/ { returninfo->x+info->y;/*模拟设备信息-通过参数传递进来*/ } structdrvdrv={ .id=1, .add=add, }; /*模拟设备信息*/ structdevdev={ .id=1, 精心整理 .x=3, .y=5, }; /*模拟总线初始化匹配设备信息和驱动代码*/ intbus() { if(dev.id==drv.id){ returndrv.add(&dev); } ... } 优点:不管加数和被加数怎么变化,不需要修改代码,仅需要修改信息 缺点:结构比较复杂 那这个设备信息和驱动分离的设计跟驱动有什么关系呢?熟悉硬件编程的同学都知道,硬件一般的构成可以使用下图简单表述: 操作外设的驱动代码逻辑,只要硬件是一样的,就不会变化。但是外设挂到不同的主机上,可能会存在I/O地址的变化,如果有中断也是一样的,中断号也可能不同。这些I/O地址和中断号就是设备信息,使用这些信息来操作控制硬件的代码就是驱动。 如果采用【例-1】的设计方式,那么同一个硬件外设接到不同的主机,或是换了地址线/中断线,设备信息就变化了,得去修改驱动。但是采用【例-2】的方式进行设计,问题就迎刃而解:不管同样的外设硬件接到哪里或是那个平台,其驱动代码逻辑并不需要改动,而仅仅需要改变下设备信息,主要的就是I/O地址和中断号。 说了这么半天,跟引入设备树有什么关系呢?华清教学使用的开发板(A8/A9)都使用DM9000网卡芯片。DM9000驱动是开源的,在主线内核源码中就有。我们每次基于A8/A9板子移植的时候,DM9000驱动并没有修改过,仅仅是选配了下,主要的工作是在板级文件中添加了设备信息。DM9000驱动使用的是platform框架,所以添加了一份DM9000网卡芯片的platform_device信息。问题来了,如果使用C代码的形式来描述设备信息,则在内核源码中,将会有多份DM9000的platform_device设备信息,造成了内核代码冗余。 解决这个问题的办法就是引入设备树,改造【例-2】来说明设备树的作用。 【例-3】实现一个代码,不仅把要使用的信息和操作代码分离开来,而且信息不是C代码编写的,而是文本配置文件保存的: structdev{ intid; intx; inty; };/*模拟设备信息结构*/ strcutdrv{ intid; int(*add)(structdev*info); };/*模拟驱动结构*/ 精心整理 intadd(structdev*info)/*模拟驱动代码*/ { returninfo->x+info->y;/*模拟设备信息-通过参数传递进来*/ } structdrvdrv={ .id=1, .add=add, }; /*模拟设备树-一个特殊的配置文件,xxx.dtbs的文本文件*/ /{ ...... Dm9000{ x=3; y=5; }; ...... }; /*模拟总线初始化匹配设备信息和驱动代码*/ intbus() { /*模拟设备树初始化处理*/ 读文件(xxx.dtbs); 解析文件内容(根据设备树的规则来解析); 生成structdev设备信息; if(dev.id==drv.id){ returndrv.add(&dev); } ... } 如果像【例-3】这样,就可以解决大量设备信息的代码冗余问题。 推而广之,系统的软硬件信息都可以使用设备树来描述。这样的话,ARMLinux社区就不会因为支持板子和驱动越来越多造成内核源码中出现很多冗余代码(主要是板级文件),仅仅需要移植者,把系统的软硬件信息通过设备树提供出来,选配一下内核代码,就可以了。 2、设备树的概述 2.1、参考资料 内核源码目录Documentation\\devicetree设备树说明文档