ARM Linux 设备树详细介绍(1)

        1. ARM&Device&Tree 起源

        Linus Torvalds 在 2011 年 3 月 17 日的 ARM Linux 邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”,引发 ARM Linux 社区的地震,随后 ARM 社区进行了一系列 的重大修正。

        在过去的 ARM Linux 中,arch/arm/plat-xxx 和 arch/arm/mach-xxx 中充斥着大 量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不 过是垃圾,如板上的 platform 设备、resource、i2c_board_info、spi_board_info 以及各种硬 件的 platform_data。读者有兴趣可以统计下常见的 s3c2410、s3c6410 等板级目录,代码量 在数万行。

        社区必须改变这种局面,于是 PowerPC 等其他体系架构下已经使用的 Flattened Device Tree(FDT)进入 ARM 社区的视野。

        Device Tree 是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在 Linux 2.6 中,ARM 架构的板极硬件细节过多地被硬编码在 arch/arm/plat-xxx 和 arch/arm/mach-xxx,采用 Device Tree 后,许多硬件的细节可以直接透 过它传递给 Linux,而不再需要在 kernel 中进行大量的冗余编码。

        Device Tree 由一系列被命名的结点(node)和属性(property)组成,而结点本身可包 含子结点。所谓属性,其实就是成对出现的 name 和 value。在 Device Tree 中,可描述的信 息包括(原先这些信息大多被 hard code 到 kernel 中):

        1、 CPU 的数量和类别

        2、 内存基地址和大小

        3、 总线和桥

        4、 外设连接

        5、 中断控制器和中断使用情况

        6、 GPIO 控制器和 GPIO 使用情况

        7、 Clock 控制器和 Clock 使用情况

        它基本上就是画一棵电路板上 CPU、总线、设备组成的树,Bootloader 会将这棵树传 递给内核,然后内核可以识别这棵树,并根据它展开出 Linux 内核中的 platform_device、 i2c_client、spi_device 等设备,而这些设备用到的内存、IRQ 等资源,也被传递给了内核, 内核会将这些资源绑定给展开的相应的设备。

        2. Device&Tree 组成和结构

        整个 Device Tree 牵涉面比较广,即增加了新的用于描述设备硬件信息的文本格式,又 增加了编译这一文本的工具,同时 Bootloader 也需要支持将编译后的 Device Tree 传递给 Linux 内核。

        DTS (device tree source) 

        dts 文件是一种 ASCII 文本格式的 Device Tree 描述,此文本格式非常人性化,适合人 类的阅读习惯。基本上,在 ARM Linux 在,一个.dts 文件对应一个 ARM 的 machine,一般 放置在内核的 arch/arm/boot/dts/目录。由于一个 SoC 可能对应多个 machine(一个 SoC 可 以对应多个产品和电路板),势必这些.dts 文件需包含许多共同的部分,Linux 内核为了简 化,把 SoC 公用的部分或者多个 machine 共同的部分一般提炼为.dtsi,类似于 C 语言的头 文件。其他的 machine 对应的.dts 就 include 这个.dtsi。譬如,对于 VEXPRESS 而言, vexpress-v2m.dtsi 就被 vexpress-v2p-ca9.dts 所引用, vexpress-v2p-ca9.dts 有如下一行:

        /include/ "vexpress-v2m.dtsi"

        当然,和 C 语言的头文件类似,.dtsi 也可以 include 其他的.dtsi,譬如几乎所有的 ARM SoC 的.dtsi 都引用了 skeleton.dtsi。

        dts(或者其 include 的.dtsi)基本元素即为前文所述的结点和属性:

                

                上述.dts 文件并没有什么真实的用途,但它基本表征了一个 Device Tree 源文件的结构:

                1 个 root 结点"/"; root 结点下面含一系列子结点,本例中为"node1" 和 "node2";

                结点"node1"下又含有一系列子结点,本例中为"child-node1" 和 "child-node2";

                各结点都有一系列属性。这些属性可能为空,如" an-empty-property";可能为字符串, 如"a-string-property";可能为字符串数组,如"a-string-list-property";可能为 Cells(由 u32 整数组成),如"second-child-property",可能为二进制数,如"a-byte-data-property"。

                下面以一个最简单的 machine 为例来看如何写一个.dts 文件。假设此 machine 的配置如 下:

                1 个双核 ARM Cortex-A9 32 位处理器;

                ARM 的 local bus 上的内存映射区域分布了 2 个串口(分别位于 0x101F1000 和 0x101F2000)、GPIO 控制器(位于 0x101F3000)、SPI 控制器(位于 0x10170000)、中 断控制器(位于 0x10140000)和一个 external bus 桥;

                External bus 桥上又连接了 SMC SMC91111 Ethernet(位于 0x10100000)、I 2 C 控制器 (位于 0x10160000)、64MB NOR Flash(位于 0x30000000); External bus 桥上连接的 I 2 C 控制器所对应的 I 2 C 总线上又连接了 Maxim DS1338 实时 钟(I 2 C 地址为 0x58)。

                其对应的.dts 文件为:

                

                   

                        

                  上述.dts 文件中,root 结点"/"的 compatible 属性 compatible = "acme,coyotes-revenge";定义 了系统的名称,它的组织形式为:,。

                   Linux 内核透过 root 结点"/"的 compatible 属性即可判断它启动的是什么 machine。 在.dts 文件的每个设备,都有一个 compatible 属性,compatible 属性用户驱动和设备的 绑定。compatible 属性是一个字符串的列表,列表中的第一个字符串表征了结点代表的确 切设备,形式为",",其后的字符串表征可兼容的其他设备。

                  可以说 前面的是特指,后面的则涵盖更广的范围。如在 arch/arm/boot/dts/vexpress-v2m.dtsi 中的 Flash 结点:

                

                compatible 属性的第 2 个字符串"cfi-flash"明显比第 1 个字符串"arm,vexpress-flash"涵盖 的范围更广。

                再比如,Freescale MPC8349 SoC 含一个串口设备,它实现了国家半导体(National Semiconductor)的 ns16550 寄存器接口。则 MPC8349 串口设备的 compatible 属性为 compatible = "fsl,mpc8349-uart", "ns16550"。其中,fsl,mpc8349-uart 指代了确切的设备, ns16550 代表该设备与 National Semiconductor 的 16550 UART 保持了寄存器兼容。

                接下来 root 结点"/"的 cpus 子结点下面又包含 2 个 cpu 子结点,描述了此 machine 上的 2 个 CPU,并且二者的 compatible 属性为"arm,cortex-a9"。

                注意 cpus 和 cpus 的 2 个 cpu 子结点的命名,它们遵循的组织形式为:[@],<>中的内容是必选项,[]中的则为可选项。name 是一个 ASCII 字符串,用于描 述结点对应的设备类型,如 3com Ethernet 适配器对应的结点 name 宜为 ethernet,而不是 3com509。如果一个结点描述的设备有地址,则应该给出@unit-address。多个相同类型设 备结点的 name 可以一样,只要 unit-address 不同即可,如本例中含有 cpu@0、cpu@1 以及 serial@101f0000 与 serial@101f2000 这样的同名结点。

                设备的 unit-address 地址也经常在其 对应结点的 reg 属性中给出。 ePAPR 标准给出了结点命名的规范。 可寻址的设备使用如下信息来在 Device Tree 中编码地址信息:

                        

                其中 reg 的组织形式为 reg = , 其中的每一组 address length 表明了设备使用的一个地址范围。address 为 1 个或多个 32 位 的整型(即 cell),而 length 则为 cell 的列表或者为空(若#size-cells = 0)。address 和 length 字段是可变长的,父结点的#address-cells 和#size-cells 分别决定了子结点的 reg 属性 的 address 和 length 字段的长度。

                在本例中,root 结点的#address-cells = ;和#size-cells = ;决定了 serial、gpio、spi 等结点的 address 和 length 字段的长度分别为 1。cpus 结点的 #address-cells = ;和#size-cells = ;决定了 2 个 cpu 子结点的 address 为 1,而 length 为 空,于是形成了 2 个 cpu 的 reg = ;和 reg = ;。external-bus 结点的#address-cells = 和#size-cells = ;决定了其下的 ethernet、i2c、flash 的 reg 字段形如 reg = ;、 reg = ;和 reg = ;。其中,address 字段长度为 0,开始的第一个 cell(0、1、2)是对应的片选,第 2 个 cell(0,0,0)是相对该片选的基地址,第 3 个 cell(0x1000、0x1000、0x4000000)为 length。特别要留意的是 i2c 结点中定义的 #addresscells = ;和#size-cells = ;又作用到了 I 2 C 总线上连接的 RTC,它的 address 字段为 0x58,是设备的 I 2 C 地址。

                root 结点的子结点描述的是 CPU 的视图,因此 root 子结点的 address 区域就直接位于 CPU 的 memory 区域。但是,经过总线桥后的 address 往往需要经过转换才能对应的 CPU 的 memory 映射。external-bus 的 ranges 属性定义了经过 external-bus 桥后的地址范围如何 映射到 CPU 的 memory 区域。

        

                ranges 是地址转换表,其中的每个项目是一个子地址、父地址以及在子地址空间的大 小的映射。

                映射表中的子地址、父地址分别采用子地址空间的#address-cells 和父地址空间 的#address-cells 大小。对于本例而言,子地址空间的#address-cells 为 2,父地址空间的 #address-cells 值为 1,因此 0 0 0x10100000 0x10000 的前 2 个 cell 为 external-bus 后片选 0 上偏移 0,第 3 个 cell 表示 external-bus 后片选 0 上偏移 0 的地址空间被映射到 CPU 的 0x10100000 位置,第 4 个 cell 表示映射的大小为 0x10000。ranges 的后面 2 个项目的含义 可以类推。

                Device Tree 中还可以中断连接信息,对于中断控制器而言,它提供如下属性:                 interrupt-controller – 这个属性为空,中断控制器应该加上此属性表明自己的身份; #interrupt-cells – 与#address-cells 和 #size-cells 相似,它表明连接此中断控制器的设备的 interrupts 属性的 cell 大小。

                在整个 Device Tree 中,与中断相关的属性还包括: interrupt-parent – 设备结点透过它来指定它所依附的中断控制器的 phandle,当结点没有 指定 interrupt-parent 时,则从父级结点继承。

                对于本例而言,root 结点指定了 interruptparent = ;其对应于 intc: interrupt-controller@10140000,而 root 结点的子结点并未指 定 interrupt-parent,因此它们都继承了 intc,即位于 0x10140000 的中断控制器。

                interrupts – 用到了中断的设备结点透过它指定中断号、触发方法等,具体这个属性含 有多少个 cell,由它依附的中断控制器结点的#interrupt-cells 属性决定。而具体每个 cell 又 是什么含义,一般由驱动的实现决定,而且也会在 Device Tree 的 binding 文档中说明。

                譬 如,对于 ARM GIC 中断控制器而言,#interrupt-cells 为 3,它 3 个 cell 的具体含义 Documentation/devicetree/bindings/arm/gic.txt 就有如下文字说明:

                        ​​​​​​​        

                另外,值得注意的是,一个设备还可能用到多个中断号。对于 ARM GIC 而言,若某设 备使用了 SPI 的 168、169 号 2 个中断,而言都是高电平触发,则该设备结点的 interrupts 属性可 定义为:interrupts = <0  168  4>,<0  169   4> ;

                除了中断以外,在 ARM Linux 中 clock、GPIO、pinmux 都可以透过.dts 中的结点和属 性进行描述。

                

                DTC (device tree compiler)

                将.dts 编译为.dtb 的工具。

                DTC 的源代码位于内核的 scripts/dtc 目录,在 Linux 内核使 能了 Device Tree 的情况下,编译内核的时候主机工具 dtc 会被编译出来,对应 scripts/dtc/Makefile 中的“hostprogs-y := dtc”这一 hostprogs 编译 target。

                在 Linux 内核的 arch/arm/boot/dts/Makefile 中,描述了当某种 SoC 被选中后,哪些.dtb 文件会被编译出来,如与 VEXPRESS 对应的.dtb 包括:

                

                

                Linux 下,我们可以单独编译 Device Tree 文件。

                当我们在 Linux 内核下运行 make dtbs 时,若我们之前选择了 ARCH_VEXPRESS,上述.dtb 都会由对应的.dts 编译出来。因 为 arch/arm/Makefile 中含有一个 dtbs 编译 target 项目。                

                 Device Tree Blob (.dtb)

                dtb 是.dts 被 DTC 编译后的二进制格式的 Device Tree 描述,可由 Linux 内核解析。通 常在我们为电路板制作 NAND、SD 启动 image 时,会为.dtb 文件单独留下一个很小的区域 以存放之,之后 bootloader 在引导 kernel 的过程中,会先读取该.dtb 到内存。

                Binding

                对于 Device Tree 中的结点和属性具体是如何来描述设备的硬件细节的,一般需要文档 来进行讲解,文档的后缀名一般为.txt。这些文档位于内核的 Documentation/devicetree/bindings 目录,其下又分为很多子目录。

                

                Bootloader

                Uboot mainline 从 v1.1.3 开始支持 Device Tree,其对 ARM 的支持则是和 ARM 内核支 持 Device Tree 同期完成。

                为了使能 Device Tree,需要编译 Uboot 的时候在 config 文件中加入

                #define CONFIG_OF_LIBFDT

                在 Uboot 中,可以从 NAND、SD 或者 TFTP 等任意介质将.dtb 读入内存,假设.dtb 放 入的内存地址为 0x71000000,之后可在 Uboot 运行命令 fdt addr 命令设置.dtb 的地址,如:

                U-Boot> fdt addr 0x71000000

                fdt 的其他命令就变地可以使用,如 fdt resize、fdt print 等。 对于 ARM 来讲,可以透过 bootz kernel_addr initrd_address dtb_address 的命令来启动内 核,即 dtb_address 作为 bootz 或者 bootm 的最后一次参数,第一个参数为内核映像的地址, 第二个参数为 initrd 的地址,若不存在 initrd,可以用 -代替。

《剩下内容请继续阅读第二篇》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726802.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pointnet++改进即插即用系列:全网首发FastKAN|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入FastKAN,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理…

360vr党建线上主题展立体化呈现企业的文化理念和品牌形象

在现代科技的引领下&#xff0c;艺术与VR虚拟现实技术相融合必将成为趋势&#xff0c;深圳VR公司华锐视点荣幸地推出VR艺术品虚拟展厅&#xff0c;为您带来前所未有的艺术观赏体验。体验者足不出户即可置身于一个充满创意与灵感的虚拟艺术空间。 我们深入了解每一位客户的需求与…

计算机网络 —— 应用层(万维网)

计算机网络 —— 应用层&#xff08;万维网&#xff09; 万维网核心组成部分特点 URLHTTP版本请求消息结构响应消息结构工作流程 Cookie如何工作主要用途安全与隐私类型 Web缓存客户端缓存&#xff08;浏览器缓存&#xff09;服务器端缓存 今天我们来了解万维网&#xff1a; 万…

元宇宙与AI推动品牌营销进入全智能时代

近日&#xff0c;在2024年T-EDGE未来科技大会上&#xff0c;30位业界领袖、产业优秀企业代表&#xff0c;分享以AI为代表的新技术赋能科技产业&#xff0c;抓住中国企业全球化、数字化营销、绿色经济、智能家居多个产业和领域的创新发展趋势&#xff0c;以四大热门议题&#xf…

ffmpeg.dll丢失怎么办,解决找不到ffmpeg.dll的多种方法分享

ffmpeg.dll 是一个动态链接库文件&#xff0c;它是FFmpeg多媒体框架的一部分。FFmpeg是一个开源项目&#xff0c;可以用来记录、转换数字音视频&#xff0c;也可以转换成不同格式的流媒体。由于它是许多媒体处理任务的核心组件&#xff0c;ffmpeg.dll 缺失或损坏可能会导致依赖…

Windows11+CUDA12.0+RTX4090如何配置安装Tensorflow2-GPU环境?

1 引言 电脑配置 Windows 11 cuda 12.0 RTX4090 由于tensorflow2官网已经不支持cuda11以上的版本了&#xff0c;配置cuda和tensorflow可以通过以下步骤配置实现。 2 步骤 &#xff08;1&#xff09;创建conda环境并安装cuda和cudnn&#xff0c;以及安装tensorflow2.10 con…

视频二维码怎么设置全屏播放?默认全屏效果的添加技巧

视频做成二维码如何全屏展示呢&#xff1f;现在很多人都会将视频生成二维码后&#xff0c;分享二维码给其他人来扫码查看视频内容&#xff0c;设置视频默认全屏播放可以带来展示更好的效果&#xff0c;那么横版和竖版视频扫码自动全屏播放是如何生成的呢&#xff1f; 视频二维…

如何用Vue3打造一个令人惊叹的极坐标图

本文由ScriptEcho平台提供技术支持 项目地址&#xff1a;传送门 使用 Vue3-ApexCharts 绘制极地区域图 应用场景 极地区域图常用于展示具有周期性或分类性数据的分布情况&#xff0c;例如不同月份的销售额、不同年龄段的人口分布等。 基本功能 此代码使用 Vue3-ApexChart…

C++ 59 之 纯虚函数和抽象类

#include <iostream> #include <string> using namespace std;class Cal { // 类中有纯虚函数&#xff0c;这个类也叫做抽象类&#xff0c;无法实现实例化 public:int m_a;int m_b;// 虚函数// virtual int getRes(){// return 0;// }// 纯虚函数 作用和虚函数…

深入探究RTOS的IPC机制----邮箱

阅读引言&#xff1a; 因为将来工作需要&#xff0c; 最近在深入学习OS的内部机制&#xff0c;我把我觉得重要的、核心的东西分享出来&#xff0c; 希望对有需要的人有所帮助&#xff0c; 阅读此文需要读友有RTOS基础&#xff0c; 以及一些操作系统的基础知识&#xff0c; 学习…

24上软考成绩预计6月底公布?附查分指南

最近&#xff0c;很多小伙伴都在问上半年成绩什么时候出来&#xff1f;每天学习群变成了祈祷群&#xff0c;都在祈祷45,45,45。按照上一次的成绩发布时间&#xff0c;从考试结束到成绩发布&#xff0c;间隔了32天。这次是不是会更快&#xff1f; 一般阅卷只要7-10天&#xff0c…

【踩坑】修复Ubuntu远程桌面忽然无法Ctrl C/V复制粘贴及黑屏

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 说在前面&#xff1a; 需要注意的是&#xff0c;我发现他应该是新开了一个窗口给我。我之前打开的东西&#xff0c;在这个新窗口里都没有了&#xff0c…

IngsollRang模块化控制器上电无显示维修

英格索兰模块化控制器是工业领域的重要设备&#xff0c;在许多工业生产过程中起着关键的控制作用。然而&#xff0c;当出现IngsollRang控制器上电无显示故障时&#xff0c;不仅会影响生产进度&#xff0c;还可能带来安全隐患。 一、IngsollRang模块化控制器故障诊断 1. 检查电源…

代码讲解——ssm+jsp+maven项目目录结构说明

1 applicationContext.xml 应用上下文配置 2 db.properties 数据库配置 3 log4j.properties日志配置 4 mybatis-config.xml mybatis配置 5 springmvc.xml springmvc配置

语音翻译软件app哪家好?三分钟带你揭秘语音翻译的奥秘~

自打前段时间我国开放了144小时的免签政策&#xff0c;现在各个旅游景点几乎随处可见来自世界各地的外国友人。倘若在大街上遇到外国游客向你问路&#xff0c;为了避免语言不通的尴尬情形&#xff0c;手里头常备着好用的语音翻译软件总是必要的&#xff01; 即使当下你还不清楚…

jar包运行脚本

start&#xff1a; # 启动项目 #!/bin/bash nohup java -jar audit-2.1.0.jar > app.log 2>&1 & quit&#xff1a; # 关闭程序 #!/bin/bash PID$(pgrep -f audit-2.1.0.jar) # 根据应用程序名称查找进程ID kill -9 $PID # 结束进程使用 sh命令运行

10W+人都在看的年度技术精选、游戏行业安全、私域、AI实践指南报告整合,码住!

在网易工作了十多年&#xff0c;不说别的&#xff0c;小智在这里光学习就学习到很多干货&#xff0c;今天将这些干货内容统一分享给同仁&#xff01;真的是集齐精华&#xff0c;大家先点赞收藏关注&#x1f44d; 往年&#xff0c;基于网易数智在娱乐社交、游戏、泛零售、政务、…

中学生数理化杂志中学生数理化杂志社中学生数理化编辑部2024年第3期目录

卷首语 坚持努力的二月河 韵致; 1 创新教育 高中化学教学中学生核心素养的培养 孙成扣; 4 核心素养视角下如何开展化学课堂教学策略 于海燕; 5《中学生数理化》投稿&#xff1a;cn7kantougao163.com 探讨初中化学实验教学中学生证据推理能力的培养策略 徐静; 6…

精华版 | 2024 Q1全球威胁报告一览

概要 Q1最热门的安全事件是XZ/liblzma后门高危漏洞。开发人员Andres Freund一次偶然情况下&#xff0c;发现了XZ/liblzma存在后门并对该漏洞进行报告。XZ/liblzma是一个广泛使用的开源工具&#xff0c;掌握该后门攻击者几乎可以访问任何运行受感染发行版的 Linux 机器。这一事…

AI时代下的自动化代码审计工具

代码审计工具分享 吉祥学安全知识星球&#x1f517;除了包含技术干货&#xff1a;Java代码审计、web安全、应急响应等&#xff0c;还包含了安全中常见的售前护网案例、售前方案、ppt等&#xff0c;同时也有面向学生的网络安全面试、护网面试等。 这两年一直都在提“安全左移”&…