Linux下的设备树机制

  1. 什么是设备树:
    ARM平台下有许多的CPU,由此衍生出不计其数的开发板型号,为了统一管理描述这些开发板内容的板级信息文件,引入了设备树机制。用.dts文件来表达这些文件,而不是采用.c文件。
    注:老版本的Linux内核并没有采用设备树机制

  2. dts,dtb和dtc
    dts是设备树源文件的扩展名,dtb则是编译后的二进制文件,dtc可以理解为编译器
    通过make dtbs编译所有的dts文件,如果要编译某一个直接在make后面加上文件名即可

  3. DTS的基本语法
    设备树也有头文件,扩展名为.dtsi。存放的是采用同一款SoC的不同型号的开发板中通用的信息提取出来放在.dtsi文件中.在Linux源文件的arch/arc/boot/dts文件下能够找到.dtsi文件.dts文件

/dts-v1/;

#include<.dtsi>

/{		//斜杠表示根节点,里面包含很多的子节点,头文件中也会有斜杠,跟这里表示的同一个
		//相当于.dts追加在头文件.dtsi之后,并且覆盖其中相同的值,类似头文件给变量赋初值,
		//.dts文件修改值
	memory{
	属性;
	......
	};

	chose{		//一个子节点
	属性;
	......
	};
}&cpu0{		//在根节点之外有类似这样的语句是向一个已有的节点里追加描述,&后面的就是节点的标签
属性;
......
};
节点的名字命名:name@address
其中address一般是外设寄存器的起始地址,有时候是设备地址,name就是外设的名字
有时候也会碰到这种类型的节点名字: label:name@address
这里的label是一个标签
  1. 设备树在根文件系统中的体现
    在系统启动以后,可以查看到设备树的文件信息。切换到/proc/device-tree目录(切换过去以后路径会变,这是一个软连接),会显示出所有的节点信息,每个节点都是一个文件夹。

  2. 节点的属性
    每一个节点都是一个具体的设备,他们有不同的属性,但是有些属性是很多外设驱动都会使用
    (1).compatible–兼容性属性
    compatible的值是一个字符串列表,记录了设备的信息,格式为"manufacturer,model", manufacture是设备制造商,model是模块对应的驱动的名字,驱动维护一个兼容性列表,记录了类似信息,如果在兼容性列表中有与compatible匹配的,那就可以选择对应的驱动程序来使用。
    (2).根节点中的compatible属性
    根节点中也有着compatible属性,前面已经说过子节点中的compatible是用来选择驱动的,而根节点的compatible则用来检测内核是否支持此设备,在没有使用设备树之前uboot会向内核传递自己的machine ID,以此来检测是否支持。
    (3).status–设备状态属性
    status的值也是一个字符串,描述设备的状态信息。"okay"表示设备可操作,"disabled"表示设备不可操作
    (4).reg属性
    属性的值一般是(address,length)对,一般都是某个外设的寄存器地址范围信息,address表示起始地址,length表示长度。
    (5).#address-cells和#size-cells
    #address-cells表示reg属性中address这个数据所占据的字长, #size-cells表示reg属性中size这个数据所占据的字长。赋值形式为#*-cells = < x >。要注意的是,这两个属性描述的是子节点的reg属性的数据的字长

  3. 驱动使用of函数来获取设备树的属性

of_find_node_by_name函数:函数通过节点名字查找指定的节点
函数原型如下:
struct device_node *of_find_node_by_name(struct device_node *from, const char *name);
from:开始查找的节点,如果为 NULL表示从根节点开始查找整个设备树。
name:要查找的节点名字。
返回值: 找到的节点,如果为 NULL表示查找失败。
of_find_compatible_node函数:根据 device_type和 compatible这两个属性查找指定的节点
函数原型如下:
struct device_node *of_find_compatible_node(struct device_node *from, const char *type, 
const char *compatible) 
from:开始查找的节点,如果为 NULL表示从根节点开始查找整个设备树。
type:要查找的节点对应的device_type属性值,可以为 NULL,表示忽略掉 device_type属性。
compatible: 要查找的节点所对应的 compatible属性列表。
返回值: 找到的节点,如果为 NULL表示查找失败
of_find_matching_node_and_match函数:通过 of_device_id匹配表来查找指定的节点
函数原型如下:
struct device_node *of_find_matching_node_and_match(struct device_node *from, 
const struct of_device_id *matches, const struct of_device_id **match)
from:开始查找的节点,如果为 NULL表示 从根节点开始查找整个设备树。
matches of_device_id匹配表,也就是在此匹配表里面查找节点。
match 找到的匹配的 of_device_id。
返回值: 找到的节点,如果为 NULL表示查找 失败
of_find_node_by_path:函数通过路径来查找指定的节点
函数原型如下:
inline struct device_node *of_find_node_by_path(const char *path) 
path:带有全路径的节点名,可以使用节点的别名,比如 “/backlight”就是 backlight这个节点的全路径。
返回值: 找到的节点,如果为 NULL表示查找失败

你可能感兴趣的:(linux内核与驱动)