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)。

相关推荐
阿扬ABCD1 小时前
ipmitool的Windows版本编译
windows·驱动开发
编程圈子1 天前
电机驱动开发学习19. 霍尔 BLDC 三段式 FOC 启动算法
驱动开发·学习·算法
咖啡星人k2 天前
MonkeyCode 架构深度解析:SDD 规范驱动开发的工程哲学
驱动开发·架构·monkeycode
小此方2 天前
Re:Linux系统篇(四十六)信号篇·四:一文串联操作系统底层:时钟中断、内核态切换、系统调用与 Linux 信号处理全解析
linux·驱动开发·信号处理
Echo_cy_4 天前
基于ZYNQ-7000的Ethernet驱动配置
linux·驱动开发·嵌入式硬件·fpga开发·ethernet·zynq
sukalot5 天前
windows网络适配器驱动开发-为多个 Windows 版本生成 WiFiCx 驱动程序
windows·驱动开发
TE-茶叶蛋6 天前
Spec-Driven Development(规范驱动开发)
驱动开发
云栖梦泽7 天前
Camera驱动开发与应用开发中的零拷贝与DMA
linux·驱动开发·嵌入式硬件
脱胎换骨-军哥7 天前
C++ 嵌入式编程实例:从寄存器操作到底层驱动开发
开发语言·c++·驱动开发
智者知已应修善业7 天前
【使用D触发器74HC175实现0001 0011 0111 1111 1110 1100 1000的循环彩灯电路。】2025-4-28
驱动开发·经验分享·笔记·硬件架构·硬件工程