RK3568 设备树基础语法讲解

news/2025/3/30 6:23:22/

文章目录

    • 一、什么是设备树(Device Tree)
    • 二、设备树基础语法
    • 三、dtb 文件、dtsi 文件、dts 文件的区别
    • 总结:
  • 四、/proc/device-tree目录
    • **`/proc/device-tree` 目录解析**
    • **1. 设备树如何加载到 `/proc/device-tree`**
    • **2. `/proc/device-tree` 目录结构解析**
      • **(1) 根目录 `/proc/device-tree/`**
      • **(2) CPU 相关信息 `/proc/device-tree/cpus/`**
      • **(3) 内存信息 `/proc/device-tree/memory/`**
      • **(4) 片上系统(SoC)信息 `/proc/device-tree/soc/`**
    • **3. `/proc/device-tree` 与 `dtb` 设备树二进制文件的关系**
    • **4. 设备树在驱动中的应用**
    • **5. 总结**


一、什么是设备树(Device Tree)

设备树(Device Tree, DT) 是一种用于描述 硬件 的数据结构,主要用于 ARM、PowerPC 及其他嵌入式系统中,以 独立于内核代码 的方式提供硬件信息。它的作用是让内核在启动时能够动态解析硬件配置,而无需对内核代码进行修改。

在 ARM 体系中,设备树广泛用于 Linux 内核、Bootloader(如 U-Boot),它解决了传统的“板级文件”模式(即在内核中硬编码硬件信息)的问题,使得同一份内核可以适用于不同的硬件平台。


二、设备树基础语法

设备树的源文件采用 DTS(Device Tree Source) 语法,类似于 C 语言结构体,主要包括 节点(node)属性(property)

1. 设备树基本结构

/ {compatible = "myboard,example";  // 兼容性信息,通常用于匹配驱动cpus {#address-cells = <1>;#size-cells = <0>;cpu@0 {compatible = "arm,cortex-a53";reg = <0>;};};memory {device_type = "memory";reg = <0x80000000 0x20000000>;  // 表示内存起始地址和大小};soc {uart@10000000 {  // 串口compatible = "ns16550";reg = <0x10000000 0x100>;clock-frequency = <24000000>;};gpio@20000000 {  // GPIOcompatible = "myvendor,gpio";reg = <0x20000000 0x1000>;interrupts = <5 1>;  // 中断号及触发方式};};
};

2. 语法解析

  • 节点(node)

    • {} 包围,表示设备或总线,通常带有地址,如 cpu@0uart@10000000
    • soc 是一个 SoC 设备的总线节点,里面包含 UART、GPIO 等子节点。
  • 属性(property)

    • key = value; 形式出现,例如 compatible = "ns16550";
    • reg = <地址 大小>; 表示设备的寄存器地址和大小。
  • 特殊属性

    • compatible:用于驱动匹配,表示设备支持的驱动类型。
    • reg:表示设备的寄存器基地址和大小。
    • interrupts:中断信息。

三、dtb 文件、dtsi 文件、dts 文件的区别

文件类型作用说明
.dts设备树源文件描述特定硬件的设备信息,最终转换为 .dtb
.dtsi设备树包含文件供多个 .dts 复用,类似 C 语言 #include
.dtb设备树二进制文件.dts 编译后生成的二进制文件,供内核加载

1. DTS 文件(设备树源文件)

DTS 是设备树的主要源文件,定义特定开发板的硬件信息,最终需要被编译为 dtb 才能被 Linux 内核识别。

示例(myboard.dts

#include "common.dtsi"  // 引入 dtsi 文件/ {model = "My Custom Board";compatible = "myvendor,myboard";memory {reg = <0x80000000 0x40000000>;  // 1GB 内存};
};

2. DTSI 文件(设备树包含文件)

DTSI(Device Tree Source Include)文件是设备树的“公共部分”,通常用于存放通用硬件配置,多个 DTS 文件可以引用它,类似 C 语言中的 #include

示例(common.dtsi

/soc {uart@10000000 {compatible = "ns16550";reg = <0x10000000 0x100>;clock-frequency = <24000000>;};
};

这里的 common.dtsi 可以被多个不同的开发板 .dts 复用。

3. DTB 文件(设备树二进制文件)

DTB(Device Tree Blob)是 DTS 文件经过编译后生成的二进制文件,Linux 内核或 Bootloader 直接加载这个文件,而不是解析 DTS 源文件。

DTS 编译生成 DTB

dtc -I dts -O dtb -o myboard.dtb myboard.dts

dtc(Device Tree Compiler)是设备树编译工具,能将 .dts 编译成 .dtb,也能反编译 .dtb.dts

DTB 反编译回 DTS

dtc -I dtb -O dts -o myboard.dts myboard.dtb

总结:

  • .dts设备树源文件,定义具体开发板的硬件信息。
  • .dtsi设备树包含文件,用于公共配置,被多个 .dts 复用。
  • .dtb设备树二进制文件,Linux 内核或 Bootloader 直接使用的文件,由 .dts 编译而成。

设备树的引入使得 Linux 内核适配不同硬件变得更简单,无需修改内核代码,只需修改设备树即可支持新的硬件平台。

四、/proc/device-tree目录

/proc/device-tree 目录解析

Linux 内核 中,/proc/device-tree设备树(Device Tree) 在系统中的一个虚拟文件系统(procfs),它提供了一个内核解析设备树后的视图,允许用户直接查看设备树信息,而无需解析 dtb 文件。


1. 设备树如何加载到 /proc/device-tree

设备树(DT, Device Tree)在系统启动时由 Bootloader(如 U-Boot) 加载,并传递给 Linux 内核,内核解析设备树 dtb 文件,并在 /proc/device-tree 下以目录树的方式映射出来,方便用户查看。

示例:

ls /proc/device-tree

可能输出:

#address-cells
#size-cells
model
compatible
memory
cpus
soc

这些文件和目录对应于 DTS(设备树源文件) 中的节点和属性。


2. /proc/device-tree 目录结构解析

设备树层级化的结构/proc/device-tree 也是如此,通常包含如下关键子目录:

(1) 根目录 /proc/device-tree/

文件 / 目录作用
model存放设备的型号,如 Raspberry Pi 4 Model B
compatible硬件的兼容性信息,通常用于驱动匹配
memory设备的内存信息
cpus/CPU 信息,包含各个 CPU 核心的详细参数
soc/片上系统(SoC)信息,包含串口、GPIO 等外设

示例:

cat /proc/device-tree/model

输出:

Raspberry Pi 4 Model B

这表明该设备是 树莓派 4B


(2) CPU 相关信息 /proc/device-tree/cpus/

ls /proc/device-tree/cpus/

可能输出:

#address-cells
#size-cells
cpu@0
cpu@1
cpu@2
cpu@3

每个 cpu@X 目录表示一个 CPU 核心。

查看某个 CPU 的信息:

cat /proc/device-tree/cpus/cpu@0/compatible

可能输出:

arm,cortex-a72

这表明 CPU 是 Cortex-A72 架构。


(3) 内存信息 /proc/device-tree/memory/

ls /proc/device-tree/memory/

可能输出:

device_type
reg

查看 reg(表示内存基地址和大小):

xxd /proc/device-tree/memory/reg

可能输出:

00000000: 00 00 00 00 08 00 00 00 00 40 00 00 00 00 00 00

这里:

  • 0x80000000 表示内存起始地址。
  • 0x40000000 表示内存大小(1GB)。

(4) 片上系统(SoC)信息 /proc/device-tree/soc/

ls /proc/device-tree/soc/

可能输出:

gpio@3f200000
uart@3f215000
  • gpio@3f200000:表示 GPIO 控制器,地址 0x3F200000
  • uart@3f215000:表示串口设备,地址 0x3F215000

查看串口信息:

cat /proc/device-tree/soc/uart@3f215000/compatible

可能输出:

brcm,bcm2835-uart

表明串口是 Broadcom BCM2835 UART


3. /proc/device-treedtb 设备树二进制文件的关系

/proc/device-tree 的内容是从 dtb 设备树二进制文件解析出来的,可以通过 dtc设备树编译器)导出原始 DTS 设备树

/proc/device-tree 转换回 DTS:

dtc -I fs -O dts -o extracted.dts /proc/device-tree

这样就可以获取系统当前使用的设备树


4. 设备树在驱动中的应用

在 Linux 设备驱动开发中,驱动程序通常会通过 /proc/device-tree 解析设备信息,加载相应的驱动。

示例:在驱动中读取 compatible 属性

struct device_node *np;
np = of_find_node_by_path("/soc/uart@3f215000");
if (np) {const char *compat;if (of_property_read_string(np, "compatible", &compat) == 0) {printk("UART Compatible: %s\n", compat);}
}
  • of_find_node_by_path():根据路径查找设备树节点。
  • of_property_read_string():读取 compatible 属性,用于驱动匹配。

5. 总结

  • /proc/device-tree 是 Linux 内核解析 设备树(DTB) 后的视图。
  • 目录结构与 DTS 设备树源码类似,允许用户直接访问设备信息。
  • 通过 /proc/device-tree 可以查询 CPU、内存、GPIO、串口等硬件信息,有助于调试嵌入式设备。
  • 可以使用 dtc 反编译 /proc/device-tree 为 DTS 设备树源码,便于分析系统当前加载的设备树配置。

设备树极大地简化了 Linux 内核对不同硬件的适配/proc/device-tree 使开发者可以轻松获取设备信息,无需深入 Linux 内核代码。


http://www.ppmy.cn/news/1583475.html

相关文章

Java: 构造方法详解

Java 构造方法详解 构造方法&#xff08;Constructor&#xff09;是 Java 类中用于初始化对象的特殊方法。以下是构造方法的全面解析&#xff1a; 一、基本概念 1. 构造方法的特点 方法名必须与类名完全相同没有返回类型&#xff08;连void都不写&#xff09;不能被static、…

mac m3 pro 部署 stable diffusion webui

什么是Stable Diffusion WebUI &#xff1f; Stable Diffusion WebUI 是一个基于Stable Diffusion模型开发的图形用户界面&#xff08;GUI&#xff09;工具。通过这个工具&#xff0c;我们可以很方便的基于提示词&#xff0c;描述一段文本来指导模型生成相应的图像。相比较通过…

DeepSeek大模型 + 自建知识库:用AI打造“专属问答机器人”

一、为什么需要“大模型自建知识库”&#xff1f; 假设你是一名汽车工程师&#xff0c;公司内部有10万份技术文档。当你想查“某型号发动机的扭矩参数”时&#xff0c;传统方式需要手动搜索文档&#xff0c;而通用大模型&#xff08;如ChatGPT&#xff09;可能答非所问&#x…

AwesomeQt分享(含源码)

AwesomeQt 这个项目包含了多个Qt组件的使用示例&#xff0c;旨在展示Qt各种强大功能的实现方式。 源码分享 github: awesome_Qtgitee: 后续同步 项目进度 QCustomPlot曲线控件示例 支持排序和筛选的列表控件示例 支持排序和筛选的表格控件示例 属性表示例 Dock窗口示例 自绘…

C++ 与 Rust 混合开发挑战攻克:从内存传递风险到零拷贝高效交换

作为一名深耕C++多年的技术专家,我时常被一个问题困扰:在系统编程中,如何在极致性能与内存安全之间找到平衡?C++以其无与伦比的灵活性和性能,成为许多高性能项目的基石,但手动内存管理却像一柄双刃剑,稍有不慎便可能导致内存泄漏或野指针。Rust的出现带来了新的希望,其…

当人类关系重构:从“相互需要”到“鹅卵石化”——生成式人工智能(GAI)认证的角色与影响

在数字化浪潮的席卷之下,人类社会正经历着前所未有的变革。人与人之间的连接方式、互动模式以及价值认同,都在悄然发生着变化。这一过程中,一个显著的现象是,人与人之间的关系逐渐从传统的“相互需要”模式,转变为一种更为复杂、多元且稳定的“鹅卵石化”结构。在此背景下…

如何用Spring AI构建MCP Client-Server架构

现代 Web 应用正加速与大语言模型&#xff08;LLMs&#xff09;深度融合&#xff0c;构建超越传统问答场景的智能解决方案。为突破模型知识边界&#xff0c;增强上下文理解能力&#xff0c;开发者普遍采用多源数据集成策略&#xff0c;将 LLM 与搜索引擎、数据库、文件系统等外…

MATLAB 控制系统设计与仿真 - 29

用极点配置设计伺服系统 方法1-前馈修正 对于一个可控的系统&#xff0c;我们知道可以用极点配置来得到系统的动态响应指标&#xff0c;但是系统有时会存在较大的静态误差。 例如&#xff1a; 系统的状态矩阵如下&#xff0c;试求取其阶跃响应。 MATLAB 代码如下&#xff1…