ARM Linux 驱动开发篇---Linux 设备树简介-- Ubuntu20.04

ARM Linux 驱动开发篇---Linux 设备树简介-- Ubuntu20.04
🎬 渡水无言个人主页渡水无言

专栏传送门: 《linux专栏》   《嵌入式linux驱动开发》
⭐️流水不争先,争的是滔滔不绝

 📚博主简介:第二十届中国研究生电子设计竞赛全国二等奖 |国家奖学金 | 省级三好学生

| 省级优秀毕业生获得者 | ZEEKLOG新星杯TOP18 | 半导纵横专栏博主 | 211在读研究生

在这里主要分享自己学习的linux嵌入式领域知识;有分享错误或者不足的地方欢迎大佬指导,也欢迎各位大佬互相三连

目录

前言

一、什么是设备树?

二、DTS、DTB 和 DTC

三、DTS编译规则

四、DTB 文件最终如何被内核使用?

总结


前言

在传统驱动中,GPIO址、中断号、时钟参数等硬件信息都硬编码在代码里,换一块开发板就要改一次驱动;而设备树通过.dts文件统一描述所有硬件资源,驱动只需通过标准 API获取资源,实现 “一次编写、多板适配”。如今设备树已经成为 Linux 驱动开发的核心规范,是每一位嵌入式 Linux 工程师必须掌握的技能。本期博客开始介绍一下设备树的相关概念。


一、什么是设备树?

设备树(Device Tree),顾名思义,就是用树形结构来描述硬件设备的信息。它的核心思想是:硬件是静态的,驱动是动态的。
设备(Device):指开发板上的所有硬件组件,如 CPU、内存控制器、I2C 控制器、SPI 控制器、GPIO 控制器、以及挂接在这些总线上的具体外设(如 LED、按键、EEPROM 等)。
树(Tree):指这些硬件设备之间的连接关系。在设备树中,硬件系统被抽象成一棵倒置的树,系统总线是树干,各个控制器(如 I2C、SPI、GPIO)是从主干分出的分支,而挂接在这些控制器上的外设(如 I2C 设备、SPI 设备)则是分支上的叶子节点。

在这棵 “树” 中:
树干是系统总线,所有的控制器都直接或间接挂接在总线上。
从主干分出了 I2C 控制器、SPI 控制器、GPIO 控制器等分支。
每个控制器分支又可以挂接具体的外设叶子节点,例如 I2C1 控制器上挂接了 FT5206 和 AT24C02,I2C2 控制器上挂接了 MPU6050。
描述这棵 “树” 的文件就是 DTS(Device Tree Source)文件,它采用特定的语法规则,将硬件的拓扑结构、地址、中断等信息清晰地记录下来。

二、DTS、DTB 和 DTC

我们刚才说了设备树源文件扩展名为.dts,但是我们在前面移植 Linux 的时候却一直在使用.dtb 文件,那么 DTS 和 DTB 这两个文件是什么关系呢?

DTS 是设备树源码文件,DTB 是将 DTS 编译以后得到的二进制文件。

将.c 文件编译为.o 需要用到 gcc 编译器。

那么将.dts 编译为.dtb需要什么工具呢?需要用到 DTC 工具!

具体流程可以如下图所示:

DTC 工具源码在 Linux 内核的 scripts/dtc 目录下, scripts/dtc/Makefile 文件内容如下:

hostprogs-y := dtc always := $(hostprogs-y) dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \ srcpos.o checks.o util.o dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o ......

可以看出,DTC 工具依赖于 dtc.c、flattree.c、fstree.c 等文件,最终编译并链接出 DTC 这个主机文件。如果要编译 DTS 文件的话只需要进入到 Linux 源码根目录下,然后执行如下命令:

make all

或:

make dtbs

“make all”命令是编译 Linux 源码中的所有东西,包括 zImage,.ko 驱动模块以及设备树,如果只是编译设备树的话建议使用“make dtbs”命令。

三、DTS编译规则

在嵌入式 Linux 开发中,同一个 ARM 架构 SoC(如 I.MX6ULL)往往可以适配多款不同的开发板,每块板子都有独立的设备树文件(.dts)。那么在编译内核时,系统如何知道该编译哪一个 DTS?又是通过什么机制进行管理的?

为了实现这种灵活、可扩展、自动匹配的设备树编译机制。

Linux 内核在arch/arm/boot/dts/Makefile 中对设备树进行统一管理。

以 I.MX6UL / I.MX6ULL / I.MX6SLL 系列为例:

dtb-$(CONFIG_SOC_IMX6UL) += \ imx6ul-14x14-ddr3-arm2.dtb \ imx6ul-14x14-ddr3-arm2-emmc.dtb \ ... dtb-$(CONFIG_SOC_IMX6ULL) += \ imx6ull-14x14-ddr3-arm2.dtb \ imx6ull-14x14-ddr3-arm2-adc.dtb \ imx6ull-14x14-ddr3-arm2-cs42888.dtb \ imx6ull-14x14-ddr3-arm2-ecspi.dtb \ imx6ull-14x14-ddr3-arm2-emmc.dtb \ imx6ull-14x14-ddr3-arm2-epdc.dtb \ imx6ull-14x14-ddr3-arm2-flexcan2.dtb \ imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb \ imx6ull-14x14-ddr3-arm2-lcdif.dtb \ imx6ull-14x14-ddr3-arm2-ldo.dtb \ imx6ull-14x14-ddr3-arm2-qspi.dtb \ imx6ull-14x14-ddr3-arm2-qspi-all.dtb \ imx6ull-14x14-ddr3-arm2-tsc.dtb \ imx6ull-14x14-ddr3-arm2-uart2.dtb \ imx6ull-14x14-ddr3-arm2-usb.dtb \ imx6ull-14x14-ddr3-arm2-wm8958.dtb \ imx6ull-14x14-evk.dtb \ imx6ull-14x14-evk-btwifi.dtb \ imx6ull-14x14-evk-emmc.dtb \ imx6ull-14x14-evk-gpmi-weim.dtb \ imx6ull-14x14-evk-usb-certi.dtb \ imx6ull-alientek-emmc.dtb \ imx6ull-alientek-nand.dtb \ imx6ull-9x9-evk.dtb \ imx6ull-9x9-evk-btwifi.dtb \ imx6ull-9x9-evk-ldo.dtb dtb-$(CONFIG_SOC_IMX6SLL) += \ imx6sll-lpddr2-arm2.dtb \ imx6sll-lpddr3-arm2.dtb \ ...

dtb-$(CONFIG_XXX) 表示使能该 CONFIG 时才会编译这些设备树。
每一行 .dtb 都对应一个 .dts 源文件。
同一个 SoC 的所有开发板设备树都放在同一个分组下。

所有使用到 I.MX6ULL 这个 SOC 的板子对应的.dts 文件都会被编译为.dtb。如果我们使用 I.MX6ULL 新做 了一个板子,只需要新建一个此板子对应的.dts 文件,然后将对应的.dtb 文件名添加到 dtb- $(CONFIG_SOC_IMX6ULL)下,这样在编译设备树的时候就会将对应的.dts 编译为二进制的.dtb 文件。

其中下面两行就是I.MX6U-ALPHA 开发板移植 Linux 系统的时候需要添加的设备树。

 imx6ull-14x14-evk-usb-certi.dtb \ imx6ull-alientek-emmc.dtb \

四、DTB 文件最终如何被内核使用?

编译好的 .dtb 是二进制设备树文件,使用流程如下:
U-Boot 启动
U-Boot 读取 imx6ull-alientek-emmc.dtb 到内存
U-Boot 使用 bootz 或 bootm 命令将 DTB 地址传递给 Linux 内核
内核启动时解析 DTB,获取硬件信息


总结

本期博客介绍了设备树的相关概念。

Read more

Flutter for OpenHarmony: Flutter 三方库 shamsi_date 助力鸿蒙应用精准适配波斯历法(中东出海必备)

Flutter for OpenHarmony: Flutter 三方库 shamsi_date 助力鸿蒙应用精准适配波斯历法(中东出海必备)

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在进行 OpenHarmony 的全球化(Internationalization)应用开发时,进军中东市场(尤其是波斯语地区)是一项充满潜力的战略。但在这些地区,用户习惯使用的并非公历(Gregorian),而是 波斯历(Shamsi/Jalali)。 1. 如何将用户的生日从公历转换成波斯历? 2. 鸿蒙应用的时间轴、日历选择器如何呈现 Jalali 格式? 3. 业务系统中的合同到期日如何按波斯历进行逻辑计算? shamsi_date 是 Dart 生态中处理波斯历法的权威库。它提供了极其简单的转换 API,是你开发鸿蒙出海应用、打入中东市场的关键技术补丁。 一、历法转换算法模型 shamsi_date 实现了公历与波斯历之间的双向精准映射。 Conversion Conversion 公历 (2024-02-20) 波斯历 (1402-12-01)

By Ne0inhk
Windows+Ubuntu 双系统安装超详细保姆级教程2026,包括系统安装、英伟达独显驱动安装以及双系统时间同步的所有过程

Windows+Ubuntu 双系统安装超详细保姆级教程2026,包括系统安装、英伟达独显驱动安装以及双系统时间同步的所有过程

本篇教程从镜像下载开始撰写。如果电脑是带有独立显卡的话,后文也有安装独显驱动的教程。同时双系统安装完成后,会遇到 Windows 系统下每次开机时间都不对的问题,也在教程后最后一并解决。开始之前请先准备好一个 16 GB 以上的 U 盘。后续也将更新帖子如何彻底完全卸载 Ubuntu。 电脑配置:Windows 11 25H2 家庭中文版,OMEN 暗影精灵 11,5060 显卡。 1. 安装盘制作 1.1 镜像下载 根据自己的需求自备一个 Ubuntu 系统镜像,或者直接去 Ubuntu 中文官网 https://ubuntu.cn/download 下载 Ubuntu 桌面系统镜像。我在这里直接下载 25.10 版本。 1.2

By Ne0inhk
大数据场景时序数据库选型指南——Apache IoTDB实践与解析

大数据场景时序数据库选型指南——Apache IoTDB实践与解析

在数字化转型持续推进的过程中,时序数据已经成为工业物联网、能源监控、大数据分析等场景中的核心数据类型。这类数据具备时间有序、采集频率高、数据总量大、查询多以时间范围为主等特点,传统关系型数据库在处理这类数据时,往往会面临写入压力大、存储成本高、查询效率不足等问题。因此,选择一款适配业务场景的时序数据库,已经成为大数据架构设计与物联网系统建设中的重要环节。 目录 一、大数据场景时序数据库选型的通用思路 二、Apache IoTDB产品定位与客观介绍 三、Apache IoTDB基础使用代码示例 四、时序数据库选型总结 本文从大数据场景的实际需求出发,梳理时序数据库选型的通用思路,并对Apache IoTDB这款面向物联网与大数据场景的时序数据库进行客观介绍,同时提供基础使用示例,为技术选型提供参考。 一、大数据场景时序数据库选型的通用思路 在进行时序数据库选型时,不需要盲目追求单一指标,而是结合自身业务规模、技术栈、运维能力、成本预算等维度综合判断,以下是行业内通用的选型关注点。 1. 写入与存储适配性 时序数据的典型特征是持续高频写入,选型时需要关注数据库对高并发

By Ne0inhk
OpenWrt部署Docker的硬核实战:内核适配调试全攻略与资源优化实战技巧

OpenWrt部署Docker的硬核实战:内核适配调试全攻略与资源优化实战技巧

文章目录 * 前言 * 一、OpenWrt 与 Docker 的集成前提 * 1.1 硬件与内核要求 * 1.2 软件依赖 * 二、Docker 环境部署与验证 * 2.1 基础服务配置 * 2.2 存储驱动适配 * 三、容器化应用部署实践 * 3.1 资源限制策略 * 3.2 Docker Compose 适配 * 四、性能优化与监控 * 4.1 容器资源监控 * 4.2 镜像精简策略 * 五、典型问题解决方案 * 5.1 端口冲突处理 * 5.2 低性能设备适配 * 六、内网穿透远程访问

By Ne0inhk