设备树
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影响,不受本节点影响。
以上是关于设备树的主要内容,如果未能解决你的问题,请参考以下文章