Linux设备树详解

桃扇骨 2021-07-26 23:19 469阅读 0赞

ARM Linux社区为什么要引入设备树

Linux之父Linus Torvalds闲来无事,在翻看ARM Linux代码的时候,有一天终于忍不住了。他在2011年3月17日的ARM Linux邮件列表中说道:“This whole ARM thing is a f*cking pain in the ass”。这句话迫使ARM Linux社区引入了设备树。

Linus Torvalds为什么会发飙呢?而ARM Linux社区的牛人为什么又乖乖地听话了?你得首先理解Linux设备驱动框架中一个非常好的设计:设备信息和驱动分离。

为了什么说明设备信息和驱动分离的概念,先来看一个简单的模拟代码实例:

【例-1】实现一个代码,把要使用的信息简单写死在代码中:

int add() /模拟驱动代码/

{

return 3+5; /模拟设备信息/

}

优点:简单

缺点:一旦加数和被加数发生变化就得改代码

改进设计如下:

【例-2】实现一个代码,把要使用的信息和操作代码分离开来:

struct dev{

int id;

int x;

int y;

}; /模拟设备信息结构/

strcut drv{

int id;

int (*add)(struct dev *info);

}; /模拟驱动结构/

int add(struct dev *info) /模拟驱动代码/

{

return info->x + info->y; /模拟设备信息-通过参数传递进来/

}

struct drv drv = {

.id = 1,

.add = add,

};

/模拟设备信息/

struct dev dev = {

.id = 1,

.x = 3,

.y = 5,

};

/模拟总线初始化匹配设备信息和驱动代码/

int bus()

{

if(dev.id == drv.id){

return drv.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代码编写的,而是文本配置文件保存的:

struct dev{

int id;

int x;

int y;

}; /模拟设备信息结构/

strcut drv{

int id;

int (*add)(struct dev *info);

}; /模拟驱动结构/

int add(struct dev *info) /模拟驱动代码/

{

return info->x + info->y; /模拟设备信息-通过参数传递进来/

}

struct drv drv = {

.id = 1,

.add = add,

};

/模拟设备树-一个特殊的配置文件,xxx.dtbs的文本文件/

/{

Dm9000{

x = 3;

y = 5;

};

};

/模拟总线初始化匹配设备信息和驱动代码/

int bus()

{

/模拟设备树初始化处理/

读文件(xxx.dtbs);

解析文件内容(根据设备树的规则来解析);

生成struct dev设备信息;

if(dev.id == drv.id){

return drv.add(&dev);

}

}

如果像【例-3】这样,就可以解决大量设备信息的代码冗余问题。

推而广之,系统的软硬件信息都可以使用设备树来描述。这样的话,ARM Linux社区就不会因为支持板子和驱动越来越多造成内核源码中出现很多冗余代码(主要是板级文件),仅仅需要移植者,把系统的软硬件信息通过设备树提供出来,选配一下内核代码,就可以了。

发表评论

表情:
评论列表 (有 0 条评论,469人围观)

还没有评论,来说两句吧...

相关阅读

    相关 设备dts详解

    原文网址:[设备树dts详解\_IT利刃出鞘的博客-CSDN博客][dts_IT_-CSDN] DTS文件结构 1.dts文件布局 ![设备树布局][watermar

    相关 Linux设备如何配置

    Linux 设备树是一种树形数据结构,用于存储系统中的设备信息。它描述了系统中每个设备的类型、功能和位置。 在 Linux 系统中,设备树由一个名为 "devicetree"

    相关 Linux设备语法详解

     Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离。在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写

    相关 linux raw设备详解

    裸设备概述 裸设备:也叫裸分区(原始分区),是一种没有经过格式化,不被Unix/Linux通过文件系统来读取的特殊字符设备。裸设备可以绑定一个分区,也可以绑定一个磁盘。

    相关 Linux设备详解

    ARM Linux社区为什么要引入设备树 Linux之父Linus Torvalds闲来无事,在翻看ARM Linux代码的时候,有一天终于忍不住了。他在2011年3月17日

    相关 Linux 设备介绍

    > 设备树的历史 > > 1、kernel最早加入设备树的历史得追溯到v2.6.23,从这个版本开始,在driver目录下多了一个of目录。当然,此时只是引入一些新想法而已。