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

相关推荐
Forsete15 小时前
LINUX驱动开发#9——定时器
linux·驱动开发·单片机
JMchen1231 天前
AI编程与软件工程的学科融合:构建新一代智能驱动开发方法学
驱动开发·python·软件工程·ai编程
南烟斋..1 天前
Linux设备驱动开发完全指南:从启动流程到Platform驱动模型
linux·驱动开发·uboot
范纹杉想快点毕业2 天前
实战级ZYNQ中断状态机FIFO设计
java·开发语言·驱动开发·设计模式·架构·mfc
yugi9878382 天前
RN8302B电表芯片驱动开发指南(基于SPI通信)
驱动开发·单片机·嵌入式硬件
2301_772204282 天前
Linux 驱动开发:杂项设备驱动与自动设备号管理
linux·运维·驱动开发
嵌入式-老费2 天前
Linux Camera驱动开发(用树莓派学习camera驱动)
驱动开发
松涛和鸣2 天前
70、IMX6ULL LED驱动实战
linux·数据库·驱动开发·postgresql·sqlserver
L_Jason先生2 天前
高效利用 Coding Agent 进行规约驱动开发 (SDD):原理、实践与未来洞察
人工智能·驱动开发·知识图谱
minglie12 天前
wsl环境下驱动开发的例子
驱动开发