设备树

Posted 四季帆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设备树相关的知识,希望对你有一定的参考价值。

1. 设备树文件的格式

2. dtb 二进制分布

2.1 分布图

设备树文件(dts)被编译成dtb文件以后,dtb内部的二进制分布情况如下:

2.2 dtb 的起始段

struct fdt_header {
    uint32_t magic;         //魔数,此字段应该应包含值0xd00dfeed(大端存储)
    uint32_t totalsize;     //device tree的整体大小(包括标题、内存预留块、结构块、字符串块、自由空间等)
    uint32_t off_dt_struct;  //结构块的偏移量
    uint32_t off_dt_strings; //字符串块的偏移量
    uint32_t off_mem_rsvmap; //内存预留块的偏移量。这些保留内存不会进入内存管理系统
    uint32_t version;        //该dtb的版本
    uint32_t last_comp_version; //兼容版本信息
    uint32_t boot_cpuid_phys;  //引导系统CPU的物理ID,应该和devicetree中该CPU节点的reg属性中给出的物理ID相同
    uint32_t size_dt_strings; //字符串块的长度
    uint32_t size_dt_struct;  //结构块的长度
}

2.3 结构块

结构块和字符串块是devicetree最重要和复杂的部分。

结构块描述了设备本身的结构和内容,结构块中有如下5种指令标识:

FDT_BEGIN_NODE (0x00000001): 标记节点的开始
FDT_END_NODE (0x00000002):   标记节点的结束
FDT_PROP(0x00000003):      标记了设备中一个属性的开始
FDT_NOP(0x00000004):       解析设备树的任何程序都将忽略FDT_NOP令牌,使用FDT_NOP标记覆盖树中的属性或节点定义,以将其从树中移除
FDT_END(0x00000009):       标记结构块的结尾

 

2.4 字符串块

字符串块包含设备树中使用的所有属性名称的字符串。为什么要将所有的属性名称放在字符串块?

其实这是一个取巧的方式,比如一个SOC的设备树文件中,有很多个节点都有compatible这样的属性,难道要备份很多份?其实不然,这些相同名字的字符串通常保留一份就可以了,无论哪个节点的属性名字是compatible,在字符串块中的偏移量都是同一个值就可以了。

其实我们平时写代码时的常量字符串如果有完全一样的,通常编译器也会优化成一句,以节省内存空间。

 

2.5 验证

可以使用工具hexdump打开编译好的.dtb文件,通过看十六进制来分析和验证各部分的分布。

 

3. 无处安放的知识点

3.1 bootloader传递设备树

bootloader需要将设备树在内存中的地址传给内核,在ARM中通过bootm或bootz命令来进行传递。bootm [kernel_addr] [initrd_addr] [dtb_addr],其中kernel_addr为内核镜像的地址,initrd_addr为initrd的地址,dtb_addr为dtb所在的地址,若initrd_addr为空,则用“-”来代替。

3.2 无题

在arm体系中,所有的DTS文件都存放在arch/arm/boot/dts/中:.dts 文件为板级定义;.dtsi文件为SOC级定义。

Linux实现了一套操作设备树的方法(函数),在drivers/of/目录下。

&lable中的&表示在lable中追加节点。

proc/device-tree/(实际上是这个目录sys/firmware/devicetreee/base/)下可以看到设备树信息,有的版本有,有的版本没有。

reg的书写受父节点的两个cells影响,不受本节点影响。

以上是关于设备树的主要内容,如果未能解决你的问题,请参考以下文章

Linux设备树语法详解

Linux设备树语法详解

Linux设备树语法详解

Linux设备树语法详解

设备树学习:内核对设备树的处理

Linux-设备树设备树