4.2uboot对设备树的支持——dtb的修改原理

article/2025/10/25 0:57:01

本节说明在uboot中修改dtb的原理

在uboot中,有一些命令支持对dtb文件进行修改

当我们想要修改dtb文件时,可以直接修改dts文件,然后编译dts文件生成新的dtb文件,再将新的dtb文件载入设备

或者,我们也可以在uboot中使用命令,直接修改dtb文件。修改完成后,再将新的dtb文件保存在板子上,以后启动时就可以使用这个新的dtb文件了。

实际上,在uboot中修改dtb的命令就是fdt。

fdt命令在最新的uboot版本中已经有支持了,但是1.1.6版本还不支持,所以需要修改uboot代码,增加支持fdt指令(从新版本中移植)。

在移植之前,先了解一下在fdt指令修改dtb的原理。

在dtb文件中修改某个属性

以修改dtb文件中的某个属性的原理为例,开始说明fdt指令修改dtb的原理。

先来回顾一下dtb文件中,属性是怎么保存的

首先是表示属性开始的token FDT_PROP(0x00000003);然后是描述该属性信息的extra data(len+nameoff);最后是value,也就是属性值,属性值的长度就是len

struct {uint32_t len;        //以字节为单位记录了属性值的长度(长度可能为0,表示一个空值);uint32_t nameoff;    //表示属性名在string block中的偏移位置;
};

 

那么,如何修改这个prop的值呢

假设,旧值长度len新值长度new_len,且new_len > len

那么,需要把原来的val所占的空间扩展一下,扩展为new_len;并且,在原来的val后面的数据,都需要往后移动一下,移动的长度为(new_len - len);移动之后,就可以把新的val写入了。

同时,属性值的长度也要更新为new_len

 另外,头部信息也需要同步修改

struct fdt_header {fdt32_t magic;			 /* magic word FDT_MAGIC */fdt32_t totalsize;		 /* total size of DT block */fdt32_t off_dt_struct;		 /* offset to structure */fdt32_t off_dt_strings;		 /* offset to strings */fdt32_t off_mem_rsvmap;		 /* offset to memory reserve map */fdt32_t version;		 /* format version */fdt32_t last_comp_version;	 /* last compatible version *//* version 2 fields below */fdt32_t boot_cpuid_phys;	 /* Which physical CPU id we'rebooting on *//* version 3 fields below */fdt32_t size_dt_strings;	 /* size of the strings block *//* version 17 fields below */fdt32_t size_dt_struct;		 /* size of the structure block */
};
  1. magic:不需要修改;
  2. totalsize:需要修改,总大小增加了(new_len - len)字节;
  3. off_dt_struct:不需要修改;
  4. off_dt_string:需要修改,偏移值增加了(new_len - len)字节;
  5. off_mem_rsvmap:不需要更改;
  6. version:不需要更改;
  7. last_comp_version:不需要更改;
  8. boot_cpuid_phys:不需要更改;
  9. size_dt_strings:不需要更改;
  10. size_dt_struct:需要更改,struct块的size增加了(new_len - len)字节;

也就是说,头部信息中有三项需要同步修改。

 dtb文件的布局:

 总结一下,修改属性的值,老值为len,新值为new_len,且new_len > len,需要以下几步:

  1. 把原属性val所占空间从len字节扩展为new_len字节:
    把老值之后的所有内容向后移动(new_len - len)字节;
  2. 把新值写入val所占的newlen字节空间,更新属性值的长度信息;
  3. 修改dtb头部信息中structure block的长度: size_dt_struct;
  4. 修改dtb头部信息中string block的偏移值: off_dt_strings;
  5. 修改dtb头部信息中的总长度: totalsize;

在dtb文件中增加一个新的属性

了解了dtb文件中属性的修改原理之后,其实其他的操作也是类似的。

比如,在某个节点中增加一个新的属性

  1. 如果在string block中没有这个属性的名字,就在string block尾部添加一个新字符串:
    属性的名字;
    并且修改dtb头部信息中string block的长度:size_dt_strings;
    修改dtb头部信息中的总长度: totalsize;

  2. 找到属性所在节点, 在节点尾部扩展一块空间, 内容及长度为(12+len):
    TAG      // 4字节, 对应0x00000003
    len      // 4字节, 表示属性的val的长度
    nameoff  // 4字节, 表示属性名的offset
    val      // len字节, 用来存放val

  3. 修改dtb头部信息中structure block的长度: size_dt_struct;

  4. 修改dtb头部信息中string block的偏移值: off_dt_strings;

  5. 修改dtb头部信息中的总长度: totalsize;

代码

从uboot官方下载地址(Index of /pub/u-boot/)下载一个支持fdt指令的版本的uboot(u-boot-2018.11-rc2.tar.bz2)。

解压创建工程,在cmd目录下有一个fdt.c文件。

里面有构造一个fdt的指令。

并且还有fdt指令的用法说明。

设置某个节点(path)的属性(prop)等于val为例,看一下代码上是怎么实现的。

fdt指令的入口函数是do_fdt

进入fdt,找到对应的设置属性的值的处理代码。

处理流程如下:

  1. 找到对应节点的偏移值,即找到对应节点(fdt_path_offset);
  2. 找到节点中的对应属性(fdt_getprop);
  3. 若节点中已经存在该属性,将旧的属性值保存下来;
  4. 解析传入的新的属性值,将新的属性值转换成字节流(fdt_parse_prop);
  5. 设置新的属性值(fdt_setprop);

先简单看一下fdt_parse_prop函数,它的作用是将传入的属性值转换成字节流

根据注释信息可以知道,传入的属性值可以是<>指定的十六进制数,也可以是[]指定的字节流,还可以是""指定的字符串

最终它们都要被转换成字节流。

再来看一下fdt_setprop函数,它的作用是设置新的属性值

fdt_setprop_placeholder函数中,调用fdt_resize_property_函数,重新规划dtb的大小

调用关系如下。

fdt_setpropfdt_setprop_placeholder       // 为新值在DTB中腾出位置fdt_get_property_w  // 得到老值的长度 oldlenfdt_splice_struct_  // 腾空间fdt_splice_  // 使用memmove移动DTB数据, 移动(newlen-oldlen)fdt_set_size_dt_struct  // 修改DTB头部, size_dt_structfdt_set_off_dt_strings  // 修改DTB头部, off_dt_stringsmemcpy(prop_data, val, len);  // 在DTB中存入新值

 


http://chatgpt.dhexx.cn/article/CLfurT9P.shtml

相关文章

DBT是什么

关于DBT DBT 是一种数据转换工作流&#xff0c;可帮助您完成更多工作&#xff0c;同时产生更高质量的结果。您可以使用 dbt 来模块化和集中分析代码&#xff0c;同时还为数据团队提供软件工程工作流中常见的护栏。在将数据模型安全部署到生产环境之前&#xff0c;通过监控和可见…

2.1设备树的规范(dts和dtb)——DTS格式

本节学习设备树的规范。 使用设备树时&#xff0c;需要编写dts文件&#xff0c;然后使用dtc编译dts文件&#xff0c;生成dtb文件。 所以本节分为两部分&#xff0c;第一部分讲解dts格式&#xff0c;第二部分讲解dtb格式。 首先看一下dts文件的布局。 DTS文件布局&#xff0…

关于EMUELC适配各种机型,DTB如何修改教程

很多爱好者留言&#xff0c;都想问关于EMUELC的dtb适配机型问题&#xff0c;这里我就出一个教程&#xff0c;如何修改dtb&#xff0c;然后去适配自己的机型&#xff0c;然后启动 。这里我只是提供方法&#xff0c;具体的调试是需要原理图进行配置。 首先&#xff0c;不管是aml…

DTBO简介

1、DTBO简介 设备树 (DT) 是用于描述“不可发现”硬件的命名节点和属性构成的一种数据结构。操作系统&#xff08;例如在 Android 中使用的 Linux 内核&#xff09;会使用 DT 来支持 Android 设备使用的各种硬件配置。硬件供应商会提供自己的 DT 源文件&#xff0c;接下来…

【DTB/DTBO 分区介绍】

如果你的 DTB/DTBO 位于专属的分区&#xff08;例如 dtb 和 dtbo 分区&#xff09;中&#xff0c;请使用以下表格结构和头文件格式&#xff1a; 数据结构 dt_table_header 仅适用于 dtb/dtbo 分区&#xff1b;您不能在kernel( image.gz) 末尾处附加此格式。如果您有一个 DTB/D…

2.2设备树的规范(dts和dtb)——DTB格式

本节讲述设备树的dtb格式。 上节讲述了dts格式。回顾上节&#xff0c;在dts文件和dtsi文件中&#xff0c;可以使用C语言的define和include&#xff0c;使用方法和作用也同C语言相同。 编写dts文件后&#xff0c;需要使用dtc工具将dts文件编译成dtb文件。dtc工具可以检查dts文…

「设备树」dtb给内核的两种工作模式

一&#xff0c;传递dtb给内核 对于传统bootloader提供两种工作模式&#xff1a;一是启动加载模式&#xff08;start loading&#xff09;&#xff0c;一是下载模式&#xff08;downloading&#xff09; 工作在启动加载模式时&#xff0c;bootloader会自动执行bootcmd命令&#…

设备树_dtb文件分析

前言&#xff1a;我之前的原计划是没有打算写设备树dtb文件分析&#xff0c;但是情势所迫啊&#xff01;&#xff0c;学习还是要一步一步来的。 在前面的章节提到过.dts文件以文本方式对系统设备树进行描述&#xff0c;经过Device Tree Compiler(dtc)将dts文件转换成二进制文件…

Linux设备树学习2 - DTB文件格式

一. DTB文件简介 DTB文件是由DTS文件通过dtc命令编译生成的二进制文件。DTS文件不能直接被内核解析&#xff0c;需要编译成DTB文件才可以直接被内核识别并解析使用的。 二. DTB文件内容布局 从上图可以看出&#xff0c;DTB由四个部分组成&#xff0c;分别是struct fdt_header&a…

setUserVisibleHint-- fragment真正的onResume和onPause方法

这个情况仅适合与多个fragment之间切换时统计&#xff0c;而非activity和fragment同时交互&#xff0c;因当时项目为首页4个fargment时长统计&#xff0c;因此适合&#xff0c;经下面网友评论指出&#xff0c;特在这里写出此问题&#xff0c;因最近项目较忙&#xff0c;具体情况…

onCreate与onStart区别,onStart与onResume区别

http://www.cnblogs.com/kofi1122/archive/2011/04/10/2011772.html Activity生命周期之我见 关于Activity生命周期的文章很多&#xff0c;而且大部分也说得很详细&#xff0c;所以作为关于这方面的内容我本来不想多说&#xff0c;但是大家可能跟我之前一样&#xff0c;在看这方…

Flutter BaseWidget 实现onResume、onPause()

熟读唐诗三百首&#xff0c;不会作诗也会吟。——孙洙 最近用Flutter开发的项目算是完成了开发到上线第一阶段了。任何一个项目开始了&#xff0c;若想追求的是更好&#xff0c;那么就需要下功夫对项目用户体验和代码效率深入的研究了。作为用户和产品经理、老板、UI、不懂技术…

Activity生命周期中onStart()和onResume()的区别

Activity生命周期中onStart()和onResume()的区别 在讲onStart()和onResume()的区别之前&#xff0c;必须清楚Activity的四种状态&#xff1a; 1.Running状态&#xff1a;一个新的Activity的启动入栈后&#xff0c;它在屏幕最前端&#xff0c;处于栈的最顶端&#xff0c;此时它…

android Activity的onPause()与onResume()

官方文档地址&#xff1a;http://www.android-doc.com/training/basics/activity-lifecycle/pausing.html#Resume Pause和Resume一个Activity 在一般的app使用中&#xff0c;前台的activity一般是会被视觉组件所遮住的&#xff0c;这就会导致activity的pause。举个例子&#x…

android中onResume、onPause等方法

程序正常启动&#xff1a;onCreate()->onStart()->onResume(); 正常退出&#xff1a;onPause()->onStop()->onDestory() 程序按back 退出&#xff1a; onPause()->onStop()->onDestory(),再进入&#xff1a;onCreate()->onStart()->onResume(); 程序按…

OnStart()方法和OnResume()方法的区别

文章目录 一、Activity的生命周期简述在讲onStart()和onResume()的区别之前&#xff0c;必须清楚Activity的四种状态&#xff1a; 二、OnStart()和OnResume()方法的区别区别&#xff1a; 总结 一、Activity的生命周期简述 在讲onStart()和onResume()的区别之前&#xff0c;必须…

简单介绍几种Java后台开发常用框架组合

01 前言 Java框架一直以来都是面试必备的知识点&#xff0c;而掌握Java框架&#xff0c;不管在成熟的大公司&#xff0c;快速发展的公司&#xff0c;还是创业阶段的公司&#xff0c;都能对当前正在开发中的系统有整体的认知&#xff0c;从而更好的熟悉和学习技术&#xff0c;这…

用IDEA进行Java后台开发(一)

想尝试着进行java后台开发&#xff0c;发现能找到的完整工程教程很多都是用eclipse开发的&#xff0c;于是照着搭了一套开发环境&#xff0c;也简单的写了一个测试代码&#xff0c;由于好几年没有使用eclipse了&#xff0c;快捷键实在用的费劲&#xff0c;遂找到了IDEA这个开发…

Java后台学习路线

2021.01.31.更新 2018.11.10更新&#xff0c;请看文章末尾惊喜 或者点击 https://blog.csdn.net/qq_40374604/article/details/83932163 本文摘自---https://blog.csdn.net/u014624241/article/details/52946378---感谢作者的分享 ①一段摘自知乎的文档 Java就业方向目前主…

Java后台开发一:环境搭建

很久之前就想做Java后台开发了&#xff0c;苦于一直没有找到合适的后台开发教程&#xff0c;某日发现一篇很不错的Java后台开发配置文章&#xff0c;记录如下&#xff1a; jdkeclipsesvnmavenmysqltomcat7.0sublime安装包和jar插件 配置管理工具-SVN http://download.csdn.net/…