内容详见《【正点原子】I.MX6U嵌入式Linux驱动开发指南》四十三章

开发板:imx6ull mini

虚拟机:VMware17

ubuntu:ubuntu20.04

一、什么是设备树

视频:第6.1讲 Linux设备树详解-什么是设备树?_哔哩哔哩_bilibili

对应《指南》43.1部分

        uboot启动时需要内核zImage 和 .dtb文件,其中dtb便是由设备树文件dts(Device Tree Source)转换而来。dts文件用树形结构来描述板级信息,即开发板上的设备信息,如CPU数量、 内存基地址、IIC接了哪些设备等等。

        bootcmd命令中,80800000就是zImage在RAM中的存放起始地址,83000000就是设备树在RAM中的存储地址。

tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000

        没有设备树以前,设备的板级信息等都在.c文件中进行配置,最后会被编码到内核里面,又臭又长。因此引入了设备树,用一个专用的文件格式.dts来描述板级信息,将这些玩意与linux分离。

        如果不同的板子有相同的信息,就可以将这部分提取出来作为一个通用文件.dtsi,其他的.dts文件直接引用就可以。

        一般.dts描述板级信息,.dtsi描述SOC级信息。

二、DTS文件

视频:第6.2讲 Linux设备树详解-DTS文件以及组织形式_哔哩哔哩_bilibili

对应《指南》43.2~3部分

2.1 编译为dtb

命令:

# 进入到Linux源码根目录下
make all     # 全部编译,包括zImage、.ko文件等等
make dtbs    # 将当前内核里所有.dts文件编译为.dtb
make XXX.dtb # 将指定的dts文件编译为dtb

示例: 

cd …………/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/
make dtbs
cd arch/arm/boot/dts/
ls *.dtb     # 此时应当可以看到一大堆的dts文件

 2.2 dts语法

        打开两个文件:linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/boot/dts下的imx6ull-alientek-emmc.dts和imx6ull.dtsi。

        打开两个文档:(4、参考资料)中的Devicetree SpecificationV0.2.pdf和Power_ePAPR_APPROVED_v1.12.pdf

/dts-v1/;

首先在imx6ull-alientek-emmc.dts开头可以看到:

/dts-v1/;

(解释在power_ePAPR_APPROVED_v1.12.pdf的96页:)
        The /dts-v1/; shall be present to identify the file as a version 1 DTS (dts files without this tag will be treated by dtc as being in the obsolete version 0, which uses a different format for integers in addition to other small but incompatible changes).
        /dts-v1/; 必须写上,将文件标识为版本1 DTS(没有此标签的DTS文件将被dtc视为过时的版本0,而旧格式在整数的表示方式等方面与版本1不兼容)

节点命名规则

(Power_ePAPR_APPROVED_v1.12.pdf 15页)

《指南》43.3.2部分

        节点名完整写法为:node-name@unit-address。其中node-name为设备名,unit-address一般是外设寄存器的起始地址,但也不一定,比如下面的例子。需要具体分析。

// imx6ull.dtsi 1096行
i2c4: i2c@021f8000 {    // i2c为name,021f8000为i2c4寄存器起始绝对地址…………
};// imx6ull-alientek-emmc.dts 245行
&i2c1 {mag3110@0e {    // 这里mag3110并不是IMX6ULL的外设,而是一个IIC外设,// 因此0e也不是外设寄存器起始地址,而是一个IIC地址…………};
};// imx6ull.dtsi 94行
intc: interrupt-controller@00a01000 {  //↑这里有个冒号,冒号前面是一个标签label,后面才是节点名// 这样可以通过 &label 来访问该节点,如&intc就可以访问interrupt-controller@00a01000节点// 比如上面的&i2c1,就可以在imx6ull.dtsi 939行找到“i2c1: i2c@021a0000”// &定义的节点内容如果没有则追加,如果已存在则替换,比如&i2c1里的内容就会替换原本i2c1: i2c@021a0000的内容…………
};

层级结构

Power_ePAPR_APPROVED_v1.12.pdf 14页

         “/”表示设备树文件的根节点,每个设备树文件只有一个根节点。

        imx6ull.dtsi和imx6ull-alientek-emmc.dts这两个文件都有一个“/”根节点,这两个“/”根节点的内容会合并成一个根节点。

2.3 设备树在系统中的体现

第6.4讲 Linux设备树详解-设备树在根文件系统中的体现以及添加自定义节点_哔哩哔哩_bilibili

        系统启动后可以在根文件系统里看到设备树的节点信息。

        内核启动时会解析设备树文件,并在/proc/device-tree目录下生成相应的设备树节点文件,存放设备树信息。cd到该路径下使用ls命令,可以看到很到诸如chosen、memory、reserved-memory、backlight等文件。

        这与imx6ull-alientek-emmc.dts中的结构一致:

        cat查看model的内容:

        这与imx6ull-alientek-emmc.dts中model的属性一致:

        cd到soc/aips-bus@02100000/i2c@021a0000下,可以看到这些文件:

        但是imx6ull.dtsi的939行下只能看到:

        clock-frequency、fxls8471@1e、mag3110@0e、name、printrl-0、printrl-names是从哪来的?用&追加的。在imx6ull-alientek-emmc.dts的245行可以找到:

        其中还修改了status,使用cat status可以看到status被覆盖为了okay。

2.4 其他特殊节点

第6.5讲 Linux设备树详解-设备树特殊节点_哔哩哔哩_bilibili

《指南》43.6部分

2.4.1 aliases

在imx6ull.dtsi的开头可以看到:

/ {aliases {can0 = &flexcan1;can1 = &flexcan2;…………};
};

同时,/soc/下定义了flexcan1:

/ {soc {flexcan1: can@02090000{……}……};……
}; 

        那么,can0 = &flexcan1; 等价于 can0 = &{/soc/can@02090000}; 或 can0 = "/soc/can@02090000";

        aliases节点的主要功能就是定义别名,以方便访问节点。不过一般会在节点命名的时候会加上label,然后通过&label来访问节点。

2.4.2 chosen

        主要目的是将uboot里的bootargs环境变量的值传给linux内核作为命令行参数cmd line

        在串口cd /proc/device-tree/chosen,可以看到bootargs、name、stdout-path三个。

但是imx6ull-alientek-emmc.dts中的chosen节点只定义了stdout-path一个:

	chosen {stdout-path = &uart1;};

        所以bootargs是从来的?(name先不管)当执行bootcmd中的bootz 80800000 - 83000000这句时,bootz层层调用,最终fdt_chosen函数读取bootargs的值并传给/chosen节点,供内核使用:

在alientek_uboot/common/fdt_common下可以找到fdt_chosen:

int fdt_chosen(void *fdt){int   nodeoffset;int   err;char  *str;		/* used to set string properties */err = fdt_check_header(fdt);if (err < 0) {printf("fdt_chosen: %s\n", fdt_strerror(err));return err;}/* find or create "/chosen" node.  如果存在子节点/chosen,则返回其偏移nodeoffset,否则创建并返回nodeoffset*/nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");  // fdt为指向设备树文件的指针,0表示根节点, chosen为要查找的子节点名称if (nodeoffset < 0)	// 失败return nodeoffset;str = getenv("bootargs");  // 从uboot的环境变量中读取bootargs的值if (str) {  // 如果bootargs不为空err = fdt_setprop(fdt, nodeoffset, "bootargs", str,  // 通过fdt_setprop向/chosen节点添加或修改bootargs属性strlen(str) + 1);if (err < 0) {  // 失败printf("WARNING: could not set bootargs %s.\n",fdt_strerror(err));return err;}}return fdt_fixup_stdout(fdt, nodeoffset);
}

2.4 修改节点

2.4.1添加自定义节点

        为方便查看,直接在imx6ull-alientek-emmc.dts的根节点下添加自定义节点:

	// 自定义节点。添加到imx6ull-alientek-emmc.dts的148行mytestnode: mytest@0101 {};
# VSCODE终端
cd .../linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek  # 到内核根目录下
make dtbs    # 编译
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb .../tftpboot/ -f  # 复制到自己存放zImage和dtb文件的目录下,如果忘了哪个路径就用vi /etc/default/tftpd-hpa命令看看# 串口
reboot    # 重启开发板ls /proc/device-tree/   # 此时应当能看到mytest@0101

                                                                                 (打错字了↓) 

2.4.2 使用&进行追加

        在imx6ull-alientek-emmc.dts文件最末尾添加:

&intc{mytestnode{};
};
// 追加给imx6ull.dtsi 94行的intc
# VSCODE终端
cd .../linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek  # 到内核根目录下
make dtbs    # 编译
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb .../tftpboot/ -f  # 复制到自己存放zImage和dtb文件的目录下,如果忘了哪个路径就用vi /etc/default/tftpd-hpa命令看看# 串口
reboot    # 重启开发板cd /proc/device-tree/interrupt-controller@00a01000/
ls        # 此时能看到mytestnode

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90823.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90823.shtml
英文地址,请注明出处:http://en.pswp.cn/web/90823.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT入门到晋级】window opencv安装及引入qtcreator(包含两种qt编译器:MSVC和MinGW)

前言 本文主要分享QT的两种编译器环境&#xff08;MSVC和MinGW&#xff09;下&#xff0c;安装及引入opencv的方法。 编译器区别 特性​​​​MSVC​​​​MinGW​​​​编译器类型​​微软专有编译器&#xff08;cl.exe&#xff09;基于GCC的开源工具链​​平台支持​​仅Wi…

字节跳动Coze Studio开源了!架构解析

Coze Studio 是字节跳动推出的一款 AI 应用开发平台&#xff0c;专注于帮助开发者快速构建、测试和部署基于大语言模型的智能应用。其整体架构围绕“低代码开发 AI 应用”的核心目标设计&#xff0c;融合了模型能力、工具集成、流程编排和多端部署等功能。以下是其整体架构的详…

Claude 4.0 终极编程指南:模型对比、API配置与IDE集成实战

Claude 4.0 终极编程指南&#xff1a;模型对比、API配置与IDE集成实战 基于官方文档及可验证数据源&#xff08;2025年7月更新&#xff09; 1 Claude 4.0 技术解析&#xff1a;对比竞品的核心优势与局限 1.1 官方性能数据&#xff08;来源&#xff1a;Anthropic技术白皮书&…

优化:Toc小程序猜你喜欢功能

引言&#xff1a;来自自创的小程序中热点接口&#xff0c;本小程序专为在校学生自提点餐使用 一、功能描述 该功能作为一个推荐的职责&#xff0c;根据用户最近行为给用户推荐用户可能喜欢去吃的店铺&#xff0c;可能比较简洁&#xff0c;但是需要设计的方面挺多的&#xff0c…

Datawhale AI 夏令营:让AI理解列车排期表 Notebook(Baseline拆解)

Step1、读取数据 import pandas as pd import requests import re import json from tqdm import tqdm# 读取数据 data pd.read_excel(data/info_table.xlsx) data data.fillna(无数据) dataStep2、注册硅基流动https://cloud.siliconflow.cnQwen/Qwen3-8B 模型可以免费使用&…

vue写的app设置角标

原生App角标&#xff08;UniApp示例&#xff09;调用plus.runtime.setBadgeNumber方法设置安卓/iOS角标&#xff1a;javascriptCopy Code// 设置角标 plus.runtime.setBadgeNumber(99); // 清除角标&#xff08;部分平台需特殊处理&#xff09; plus.runtime.setBadgeNumber(0)…

GAN/cGAN中到底要不要注入噪声

MelGAN论文MelGAN针对的是从mel谱生成语音&#xff0c;里面说当条件很强的时候&#xff0c;随机噪声就没啥用了&#xff0c;因此没将noise注入到生成器中&#xff1b;运用的判别器也仅有1个输入&#xff0c;不是cGAN的形式image-to-image translation with conditional adversa…

备份一下我的 mac mini 的环境变量配置情况

export PATH“/opt/homebrew/bin:$PATH” #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! export SDKMAN_DIR“HOME/.sdkman"[[−s"HOME/.sdkman" [[ -s "HOME/.sdkman"[[−s"HOME/.sdkman/bin/sdkman-init.sh” ]] && so…

JVM学习日记(十)Day10

G1回收器 这一篇是详细说明G1回收器的&#xff0c;因为他相对来说确实是个缝合怪&#xff0c;上篇的内容又太多了所不清楚&#xff0c;所有这一篇进行详细的说明&#xff0c; 第一个呢就是其实G1是兼顾并行和并发的&#xff0c;简单来说就是既可以并行也可以并发&#xff0c;…

使用IP扫描工具排查网络问题

随着企业的发展&#xff0c;网络中会新增各类设备&#xff0c;从台式机、服务器到物联网设备和虚拟机&#xff08;VMs&#xff09;&#xff0c;所有这些设备都通过复杂的子网和虚拟局域网&#xff08;VLAN&#xff09;相连。 这种复杂性给 IT 团队带来了压力&#xff0c;他们需…

Wireshark TS | 发送数据超出接收窗口

前言 来自于测试中无意发现到的一个接收窗口满的案例&#xff0c;特殊&#xff0c;或者可以说我以前都没在实际场景中见过。一开始都没整太明白&#xff0c;花了些精力才算是弄清楚了些&#xff0c;记录分享下。 问题说明 在研究拥塞控制的慢启动阶段时&#xff0c;通过 packet…

C语言自定义数据类型详解(四)——联合体

好的&#xff0c;接下来我们来学习最后一个自定义数据类型——联合体。 一、什么是联合体&#xff1a; 联合体又叫共用体&#xff0c;用关键字union来进行定义。又因为所有的成员变量共用同一段内存空间&#xff08;关于这一点&#xff0c;我们不久就会加以验证&#xff09;&…

[python][flask]Flask-Login 使用详解

1. 简介Flask-Login 是 Flask 的一个扩展&#xff0c;专门用于处理用户认证相关的功能。它提供了用户会话管理、登录/注销视图、记住我功能等常见认证需求&#xff0c;让开发者能够快速实现安全的用户认证系统。2. 安装与基础配置首先&#xff0c;需要安装 Flask-Login&#xf…

【WebGPU学习杂记】WebAssembly中的relaxed_madd指令到底做了什么?

relaxed_madd 这条指令到底做了什么核心&#xff1a;relaxed_madd 是一个分量级别 (Component-wise) 的操作 首先&#xff0c;最重要的一点是&#xff1a;v128.relaxed_madd<f32>(a, b, c) 不是矩阵乘法。它是一个在三个向量 a, b, c 之间进行的、逐个分量的、并行的融合…

【全新上线】境内 Docker 镜像状态监控

境内 Docker 镜像状态监控&#xff1a;您的 Docker 加速伴侣 在当今云计算和容器化技术飞速发展的时代&#xff0c;Docker 已成为开发者不可或缺的工具。然而&#xff0c;对于身处国内的用户而言&#xff0c;访问境外 Docker Hub 等镜像仓库时常会遭遇网络延迟和连接不稳定的困…

Visual Studio中部署PaddleOCRv5 (借助ncnn框架)

PaddleOCRv5_ncnn PaddleOCRv5 在Visual Studio中进行图片OCR检测&#xff08;ncnn框架open-mobile实现)&#xff0c;尝试对nihui的ncnn-android-ppocrv5检测算法的剥离与移植。 本项目Github链接如下&#xff1a;PaddleOCRv5_ncnn 写在前面 本仓库代码是基于nihui的ncnn-a…

中级全栈工程师笔试题

解释ACID特性&#xff0c;如何在node.js中实现事务操作针对React单页应用&#xff0c;请提供至少5种性能优化方案&#xff0c;并解释其原理&#xff1a; 减少首屏加载时间优化渲染性能资源加载策略状态管理优化代码分割方案 如何防止以下攻击&#xff1a; JWT令牌挟持Graph QL查…

Windows---动态链接库Dynamic Link Library(.dll)

DLL的“幕后英雄”角色 在Windows操作系统的生态中&#xff0c;有一类文件始终扮演着“幕后英雄”的角色——它们不像.exe文件那样直接呈现为用户可见的程序窗口&#xff0c;却支撑着几乎所有应用程序的运行&#xff1b;它们不单独执行&#xff0c;却承载着系统与软件的核心功…

深入分析计算机网络传输层和应用层面试题

三、传输层面试题&#xff08;Transmission Layer&#xff09;传输层位于 OSI 七层模型的第四层&#xff0c;它的核心任务是为两个主机之间的应用层提供可靠的数据传输服务。它不仅承担了数据的端到端传输&#xff0c;而且还实现了诸如差错检测、数据流控制、拥塞控制等机制&am…

【RH134 问答题】第 2 章 调度未来任务

目录crontab 文件中的用户作业时间格式怎么解释&#xff1f;如果需要以当前用户身份计划周期性作业&#xff0c;在上午 8 点到晚上 9 点之间每两分钟一次输出当前日期和时间&#xff0c;该作业只能在周一到周五运行&#xff0c;周六或周日不能运行。要怎么做&#xff1f;要计划…