设备树基础

xx.dts:device tree source设备树源文件

xx.dtb:device tree binary 设备树二进制文件

xx.dtc:device tree compiler 设备树编译器,作用:将dts转为dtb

dtc文件的Makefile如下:它在目录scripts\dtc\Makefile下

在linux的源码目录下输入make或make all会编译出all依赖的所有目标,包括zImage,.ko文件和驱动,输入 make tdbs只编译目标dtbs对应的文件也就是所有的设备树文件

而设备树文件是众多的,一个板子就对应一个设备树文件,如何编译我们想要的设备树文件呢,那当然是看设备树文件对应的makefile,在目录arch\arm\boot\dts\Makefile如下:

以后为我们要自己做一块板子时,将板子设备树写好后,将对应的dtb文件名字加入进来,在编译设备树时自然就会编译它

DTS语法

  1. 设备树也支持头文件,设备树的头文件后缀名为:.dtsi

  1. 设备树文件永include可以包含的头文件包括.h,.dtsi,.dts三种

一般来说,.dtsi文件用于描述soc的内部外设信息,如:cpu架构,主频,I2C,我们不需要改变。比如I.mx6ull.dtsi,要看懂它先得学一下dts语法

  1. / 它表示根节点

  1. 节点命名法则:

node-name:节点名字,是ASCLL字符串

unit-address是节点地址,没有可以省略

可以用标签代替节点名字,避免节点名字太长不方便使用,用法如下:

访问该节点时,用&label访问,不用标签则需使用全路径

  1. 属性

属性的名字可以随便取,但是属性的值却有三种取值

  1. compatiable:兼容属性,属性值为字符串列表,字符串值之间以逗号隔开,它的值是优先匹配到的字符串

  1. rag属性表示设备的起始地址和大小

  1. #adress-cells和#size-cells属性

一个cell表示一个32位数据,adress与size属性是用来设置子节点的rag属性

eg:

它表示子节点的起始地址是一个用32位数据表示的数,大小也是。

  1. status属性

要用到的模块值设置为“ok";不用设置为”disable“。fail与fail-ss一般不用

e.chosen属性

chosen节点下面的bootargs属性下面保存的便是我们设置uboot的该参数值,具体如下

f.model 属性

它的值也一个字符串,一般 model 属性描述设备模块信息,比如名字什么的

如何编写dts

.dtsi文件是对用这个芯片一系列板子所共用的头文件,一般不会更改,它里面也是设备树的一系列描述,主要是片内外设资源的描述。

我们通常是通过追加的方式去更改或者写设备树:&label

设备树文件存在的形式是:proc/device-tree/目录下,如图

属性的存在形式是文件,图中白色

子节点的存在形式是目录,图中蓝色

Linux内核解析dtb文件

具体实现不用管,知道在启动内核后,unflatten_dt_node函数会去解析设备节点即可

设备树常用操作函数:of函数集

  1. linux用device_node结构体来描述一个设备节点

  1. 节点查找函数,定义在linux内核源码的include/linux/of.h中

  1. of_find_node_by_name()

作用:通过节点名字查找节点

参数1:开始查找的节点位置,NULL表示从根节点开始查找

参数2:节点名字

返回值:成功:找到的节点;失败:NULL

  1. of_find_node_by_type()

参数1:开始查找的节点位置

参数2:要查找的节点对应的 type 字符串,也就是 device_type 属性

返回值:查找成功返回找到的节点,失败为NULL

  1. of_find_compatible_node()

from:开始查找的节点,如果为 NULL 表示从根节点开始查找整个设备树。

type:要查找的节点对应的 type 字符串,也就是 device_type 属性值,可以为 NULL,表示

忽略掉 device_type 属性。

compatible:要查找的节点所对应的 compatible 属性列表。

返回值:找到的节点,如果为 NULL 表示查找失败

  1. of_find_matching_node_and_match()

from:开始查找的节点,如果为 NULL 表示从根节点开始查找这个设备。

matches:of_device_id 匹配表,也就是在此匹配表里面查找节点。

match:找到的匹配的 of_device_id。

返回值:找到的节点,如果为 NULL 表示查找失败

  1. of_find_node_by_path ()

path:带有全路径的节点名,可以使用节点的别名

返回值:找到的节点,如果为 NULL 表示查找失败

  1. 查找父/子节点的 OF 函数

  1. of_get_parent ()

作用:于获取指定节点的父节点

参数:要查找的父节点的节点。

返回值:找到的父节点。

b.of_get_next_child()

作用:于获取指定节点的子节点(迭代查找)

node:父节点。

prev:前一个子节点,也就是从哪一个子节点开始迭代的查找下一个子节点。可以设置为

NULL,表示从第一个子节点开始。

返回值:找到的下一个子节点。

  1. 提取属性值的 OF 函数

  1. of_find_property()

作用:查找指定的属性

np:设备节点。

name: 属性名字。

lenp:属性值的字节数

返回值:找到的属性。

b.of_property_count_elems_of_size()

作用:查找元素属性数量

np:设备节点。

proname: 需要统计元素数量的属性名字。

elem_size:元素长度。

返回值:得到的属性元素数量。

c.of_property_read_u32_index()

作用:从属性中获取指定标号的 u32 类型数据值

np:设备节点。

proname: 要读取的属性名字。

index:要读取的值标号。

out_value:读取到的值

返回值:0 读取成功,负值,读取失败,-EINVAL 表示属性不存在,-ENODATA 表示没有

要读取的数据,-EOVERFLOW 表示属性值列表太小。

d.of_property_read_u8_array ()

of_property_read_u16_array ()

of_property_read_u32_array ()

of_property_read_u64_array ()

  1. 其他常用的 OF 函数

  1. of_device_is_compatible()

作用:查找compatiable属性之中是否含有compat指定的字符串

参数:device:设备节点。

compat:要查看的字符串。

返回值:0,节点的 compatible 属性中不包含 compat 指定的字符串;正数,节点的 compatible

属性中包含 compat 指定的字符串

b.of_get_address()

作用:获取地址相关属性,如reg,assigned-addresses属性

dev:设备节点。

index:要读取的地址标号。

size:地址长度。

flags:参数,比如 IORESOURCE_IO、IORESOURCE_MEM 等

返回值:读取到的地址数据首地址,为 NULL 的话表示读取失败

c.of_translate_address()

作用:将从设备树读到的虚拟地址转换为物理地址

dev:设备节点。

in_addr:要转换的地址。

返回值:得到的物理地址,如果为 OF_BAD_ADDR 的话表示转换失败。

d.of_address_to_resource()

linux内核使用resource结构体来描述一段内存空间

对于 32 位的 SOC 来说,resource_size_t 是 u32 类型的,

start:内存起始地址

end:内存结束地址

name:资源名字

flags:资源标志位,一般表示资源的类型

作用:将reg属性值转化为resource结构体

对于of_address_to_resource:

dev:设备节点。

index:地址资源标号。

r:得到的 resource 类型的资源值。

返回值:0,成功;负值,失败。

e.of_iomap()

作用:of_iomap 函数用于直接内存映射,以前的ioremap也可以,但是在设备树中习惯用of_iomap函数来完成内存映射。

np:设备节点。

index:reg 属性中要完成内存映射的段,如果 reg 属性只有一段的话 index 就设置为 0。

返回值:经过内存映射后的虚拟内存首地址,如果为 NULL 的话表示内存映射失败。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值