63.dtb展开成device_node

内核是不认识dtb文件的,所以在初始化时会将dtb转化成可识别的device_node

cpp 复制代码
struct device_node {
    const char *name;              // 节点名称(如 "cpu")
    const char *full_name;         // 节点全路径(如 "/cpus/cpu@0")
    struct property *properties;   // 指向该节点的属性链表(如 reg, compatible 等)
    struct device_node *parent;    // 指向父节点
    struct device_node *child;     // 指向第一个子节点
    struct device_node *sibling;   // 指向兄弟节点
    // ... 其他内核管理相关的字段(如 phandle, flags 等)
};

device_node 大概长这样

展开过程

1. 核心流程概览

DTB 在内存中是连续的二进制数据,而 device_node 是通过指针相互连接的结构体对象。转换过程主要分为:扫描、内存分配、填充

阶段一:初始校验与早扫描

在正式转换前,内核会先通过 setup_machine_fdt() 验证 DTB 的合法性(Magic Number、CRC等),并扫描一些紧急信息(如内存基址、命令行参数 chosen 节点)。

阶段二:反扁平化(Unflattening)

这是最核心的一步,主要调用流程如下: start_kernel() -> setup_arch() -> unflatten_device_tree() -> __unflatten_device_tree()

2. 关键算法与步骤

__unflatten_device_tree() 会对 FDT 字节码进行两次遍历

第一轮遍历:计算空间

内核首先扫描整个 DTB,计算出转换后所有 device_node 结构体以及属性 property 所需的总内存大小。

  • 统计节点个数。

  • 统计属性个数及属性值的总长度。

第二轮遍历:解析并填充

在申请到足够的连续内存后,内核再次扫描 DTB,开始构建逻辑树:

  1. 创建节点 :遇到 OF_DT_BEGIN_NODE 标志时,分配并初始化一个 struct device_node

  2. 建立父子关系 :利用栈的思想,根据 DTB 的嵌套结构,设置节点的 parentchildsibling 指针。

  3. 解析属性 :遇到 OF_DT_PROP 标志时,解析属性名称和值,封装进 struct property 结构,并挂载到对应节点的 properties 链表上。

  4. 生成 Full Name :根据路径生成节点的完整路径名(如 /soc/uart@e0001000)。

相关推荐
车载操作系统---攻城狮18 小时前
GD32vw53h 开发板(Uart功能)测评 - 完整版
驱动开发
一晌小贪欢19 小时前
用 PyQt5 做一个「批量目录重命名」工具,并打包成带图标的 EXE
开发语言·驱动开发·python·python基础·python小白
KL's pig/猪头/爱心/猪头1 天前
写一个rv1106的led驱动3-功能函数编写
linux·驱动开发·rv1106
自由的好好干活2 天前
PLX9x5x_PCI_Driver 中断从注册到调用完整流程
驱动开发·ai编程
自由的好好干活2 天前
PLX 9x5x PCI 驱动程序执行流程详解(Qoder生成)
驱动开发·ai编程
viqjeee2 天前
ALSA驱动开发流程
数据结构·驱动开发·b树
自由的好好干活3 天前
win7驱动开发环境搭建
驱动开发
敏叔V5873 天前
AI应用开发框架对比:LangChain vs. Semantic Kernel vs. DSPy 深度解析
人工智能·驱动开发·langchain
似霰4 天前
AIDL Hal 开发笔记4----驱动开发
android·驱动开发·framework·hal
yuanmenghao4 天前
车载Linux 系统问题定位方法论与实战系列 - OOM 与资源耗尽:系统是如何被“慢慢拖死”的
linux·运维·服务器·网络·驱动开发·自动驾驶