在Linux系統中,設備樹是一種描述硬體配置的樹形資料結構,它起源於Open Firmware標準,用於提供作業系統軟體和硬體之間的接口,啟動和運行系統。設備樹可以減少核心為支援新硬體所需的改變,提高程式碼重複使用,加速Linux支援包的開發,使得單一核心鏡像能支援多個系統。本文將介紹Linux設備樹dts移植的基本步驟和方法,包括設備樹的資料儲存格式、原始碼描述語法、U-Boot和Linux核心對設備樹的支援和解析過程等。
#關鍵字:扁平設備樹; DTS; PowerPC; Linux
IBM、Sun 等廠商的伺服器最初都採用了Firmware(一種嵌入到硬體設備中的程序,用
於提供軟體和硬體之間的介面),用於初始化系統配置,提供作業系統軟體和硬體之間的接
口,啟動和運行系統。後來為了標準化和相容性,IBM、Sun 等聯合推出了韌體介面IEEE 1275
標準,讓他們的伺服器如IBM PowerPC pSeries,Apple PowerPC,Sun SPARC 等皆採用Open
Firmware,運行時建構系統硬體的設備樹資訊傳遞給內核,進行系統的啟動運行[1]。這樣
做的好處有,減少核心對系統硬體的嚴重依賴,利於加速支援包的開發,降低硬體帶來的變
化需求和成本,降低對核心設計和編譯的要求。
隨著 Linux/ppc64 核心的發展,核心程式碼從原來的arch/ppc32 和arch/ppc64 逐漸遷移到
統一的arch/powerpc 目錄,並在核心程式碼引入Open Firmware API 以使用標準韌體介面[2]。
Linux 核心在運行時,需要知道硬體的一些相關資訊。對於使用ARCH=powerpc 參數編譯的
核心鏡像,這個資訊需要基於Open Firmware 規範,以設備樹的形式存在[3]。這樣內核在啟
動時讀取掃描Open Firmware 提供的設備樹,從而獲得平台的硬體設備信息,搜尋匹配的設
備驅動程式並將該驅動程式綁定到裝置。
在嵌入式 PowerPC 中,一般使用U-Boot 之類的系統引導程式碼,而不採用Open Firmware。
早期的U-Boot 使用include/asm-ppc/u-boot.h 中的靜態資料結構struct bd_t 將板子基本資訊傳
遞給內核,其餘的由內核處理。這樣的介面不夠靈活,硬體發生變化就需要重新客製化編譯燒
寫入引導程式碼和內核,也不再適應現在的內核。為了適應核心的發展及嵌入式PowerPC
平台的千變萬化,吸收標準Open Firmware 的優點,U-Boot 引入了扁平設備樹FDT 這樣的
動態接口,使用一個單獨的FDT blob(二進位大對象,是一個可以儲存二進位的容器)
儲存傳遞給核心的參數[3]。一些確定訊息,例如cache 大小、中斷路由等直接由設備樹提供,
而其他的信息,例如eTSEC 的MAC 位址、頻率、PCI 匯流排數目等由U-Boot 在運作時修改。
U-Boot 使用扁平設備樹取代了bd_t,而且不再保證對bd_t 的後向相容。
2 裝置樹概念
#
簡單的說,設備樹是一種描述硬體配置的樹狀資料結構,有且僅有一個根節點[4]。它包
含了有關CPU、實體記憶體、匯流排、串列埠、PHY 以及其他週邊設備資訊等。該樹繼承了Open
Firmware IEEE 1275 設備樹的定義。作業系統能夠在啟動時對此結構進行語法分析,以此配
置內核,載入對應的驅動。
3 裝置樹儲存格式
U-Boot 需要將裝置樹在記憶體中的儲存位址傳給核心。該樹主要由三大部分組成:頭
(Header)、結構塊(Structure block)、字串塊(Strings block)。設備樹在記憶體中的存
儲佈局圖1 如下:
圖1 設備樹儲存格式圖
Fig1 The layout of a DT block
3.1 頭(頭)
頭主要描述設備樹的基本訊息,如設備樹魔數標誌、設備樹塊大小、結構塊的偏移位址
等,其具體結構boot_param_header 如下。這個結構中的值都是以大端模式表示,且偏移
3.2 結構塊(structure block)
#
扁平設備樹結構塊是線性化的樹狀結構,和字串塊一起組成了設備樹的主體,以節點
形式保存目標板的設備資訊。在結構塊中,節點起始標誌為常值宏OF_DT_BEGIN_NODE,
節點結束標誌為宏OF_DT_END_NODE;子節點定義在節點結束標誌前。一個節點可以概
括為以OF_DT_BEGIN_NODE 開始,包含節點路徑、屬性列表、子節點列表,最後以
3.3 字符串块(Strings block)
为了节省空间,将一些属性名,尤其是那些重复冗余出现的属性名,提取出来单独存放
到字符串块。这个块中包含了很多有结束标志的属性名字符串。在设备树的结构块中存储了
这些字符串的偏移地址,这样可以很容易地查找到属性名字符串。字符串块的引入节省了嵌
入式系统较为紧张的存储空间。
4 设备树源码DTS 表示
设备树源码文件(.dts)以可读可编辑的文本形式描述系统硬件配置设备树,支持C/C++
方式的注释,该结构有一个唯一的根节点“/”,每个节点都有自己的名字并可以包含多个
子节点。设备树的数据格式遵循了Open Firmware IEEE standard 1275。本文只简述设备树的
数据布局及语法,Linux 板级支持包开发者应该详细参考IEEE 1275 标准[5]及其他文献[2] [4]。
为了说明,首先给出基于PowerPC MPC8349E 处理器的最小系统的设备树源码示例。
可以看到,这个设备树中有很多节点,每个节点都指定了节点单元名称。每一个属性后面都
给出相应的值。以双引号引出的内容为ASCII 字符串,以尖括号给出的是32 位的16 进制
值。这个树结构是启动Linux 内核所需节点和属性简化后的集合,包括了根节点的基本模式
信息、CPU 和物理内存布局,它还包括通过/chosen 节点传递给内核的命令行参数信息。
/ { model = "MPC8349EMITX"; compatible = "MPC8349EMITX", "MPC834xMITX", "MPC83xxMITX"; \#address-cells = ; /* 32bit address */ \#size-cells = ; /* 4GB size */ cpus { \#address-cells = ; \#size-cells = ; PowerPC,8349@0 { device_type = "cpu"; reg = ; d-cache-line-size = ; /* 32 Bytes */ i-cache-line-size = ; d-cache-size = ; /* L1 dcache, 32K */ i-cache-size = ; timebase-frequency = ; /* from bootloader */ bus-frequency = ; clock-frequency = ; }; }; memory { device_type = "memory"; reg = ; /* 256MB */ }; chosen { name = "chosen"; bootargs = "root=/dev/ram rw console=ttyS0,115200"; linux,stdout-path = "/soc8349@e0000000/serial@4500"; }; };
4.1 根节点
设备树的起始点称之为根节点”/”。属性model 指明了目标板平台或模块的名称,属性
compatible 值指明和目标板为同一系列的兼容的开发板名称。对于大多数32 位平台,属性
#address-cells 和#size-cells 的值一般为1。
4.2 CPU 节点
/cpus 节点是根节点的子节点,对于系统中的每一个CPU,都有相应的节点。/cpus 节点
没有必须指明的属性,但指明#address-cells = 和 #size-cells = 是个好习惯,这同时指
明了每个CPU 节点的reg 属性格式,方便为物理CPU 编号。
此节点应包含板上每个CPU 的属性。CPU 名称一般写作PowerPC,,例如
Freescale 会使用PowerPC,8349 来描述本文的MPC8349E 处理器。CPU 节点的单元名应该是
cpu@0 的格式,此节点一般要指定device_type(固定为”cpu”),一级数据/指令缓存的表项
大小,一级数据/指令缓存的大小,核心、总线时钟频率等。在上面的示例中通过系统引导
代码动态填写时钟频率相关项。
4.3 系统内存节点
此节点用于描述目标板上物理内存范围,一般称作/memory 节点,可以有一个或多个。
当有多个节点时,需要后跟单元地址予以区分;只有一个单元地址时,可以不写单元地址,
默认为0。
此节点包含板上物理内存的属性,一般要指定device_type(固定为”memory”)和reg
属性。其中reg 的属性值以的形式给出,如上示例中目标板内存起始
地址为0,大小为256M 字节。
4.4 /chosen 节点
这个节点有一点特殊。通常,这里由Open Firmware 存放可变的环境信息,例如参数,
默认输入输出设备。
这个节点中一般指定bootargs 及linux,stdout-path 属性值。bootargs 属性设置为传递给内
核命令行的参数字符串。linux,stdout-path 常常为标准终端设备的节点路径名,内核会以此作
为默认终端。
U-Boot 在1.3.0 版本后添加了对扁平设备树FDT 的支持,U-Boot 加载Linux 内核、
Ramdisk 文件系统(如果使用的话)和设备树二进制镜像到物理内存之后,在启动执行Linux
内核之前,它会修改设备树二进制文件。它会填充必要的信息到设备树中,例如MAC 地址、
PCI 总线数目等。U-Boot 也会填写设备树文件中的“/chosen”节点,包含了诸如串口、根
设备(Ramdisk、硬盘或NFS 启动)等相关信息。
4.5 片上系统SOC 节点
此节点用来描述片上系统SOC,如果处理器是SOC,则此节点必须存在。顶级SOC 节
点包含的信息对此SOC 上的所有设备可见。节点名应该包含此SOC 的单元地址,即此SOC
内存映射寄存器的基址。SOC 节点名以/soc的形式命名,例如MPC8349 的SOC
节点是”soc8349″。
在属性中应该指定device_type(固定为”soc”)、ranges、bus-frequency 等属性。ranges
属性值以
SOC 设备子节点,应该在设备树中尽可能详细地描述此SOC 上的外围设备。如下给出带有
看门狗设备的SOC 节点DTS 示例。
soc8349@e0000000 { \#address-cells = ; \#size-cells = ; device_type = "soc"; compatible = "simple-bus"; ranges = ; /* size 1MB */ reg = ; bus-frequency = ; /* from bootloader */ { device_type = "watchdog"; compatible = "mpc83xx_wdt"; reg = ; /* offset: 0x200 */ }; };
4.6 其他设备节点
分级节点用来描述系统上的总线和设备,类似物理总线拓扑,能很方便的描述设备间的
关系。对于系统上的每个总线和设备,在设备树中都有其节点。对于这些设备属性的描述和
定义请详细参考IEEE 1275 标准及本文参考文献[2]。
设备树的中断系统稍显复杂,设备节点利用interrupt-parent 和interrupts 属性描述到中
断控制器的中断连接。其中interrupt-parent 属性值为中断控制器节点的指针,#interrupts 属
性值描述可触发的中断信号,其值格式与中断控制器的interrupt-cells 属性值有关。一般
#interrupt-cells 属性值为2,interrupts 属性就对应为一对描述硬件中断号和中断触发方式的
十六进制值。
5 扁平设备树编译
根据嵌入式板的设备信息写设备树源码文件(.dts)通常比较简单,但是手写二进制的
扁平设备树(.dtb)就显得比较复杂了。设备树编译器dtc 就是用来根据设备树源码的文本
文件生成设备树二进制镜像的。dtc 编译器会对输入文件进行语法和语义检查,并根据Linux
内核的要求检查各节点及属性,将设备树源码文件(.dts)编译二进制文件(.dtb),以保证
内核能正常启动。dtc 编译器的使用方法如下所示[6]:
dtc [ -I dts ] [ -O dtb ] [ -o opt_file ] [ -V opt_version ] ipt_file
2.6.25 版本之后的内核源码已经包含了dtc 编译器。在配置编译内核时选中
CONFIG_DTC,会自动生成设备树编译器dtc。将编写的目标板设备树文件mpc8349emitx.dts
放到内核源码的arch/powerpc/boot/dts/目录下,利用内核Makefile 生成blob 的简单规则,使
用以下命令亦可完成设备树的dtc 编译:
$ make mpc8349emitx.dtb
6 U-Boot 相关设置说明
为使 U-Boot 支持设备树,需要在板子配置头文件中设置一系列宏变量。如本文在
MPC8349E 处理器目标板中移植的U-Boot 配置如下: /* pass open firmware flat tree */ \#define CONFIG_OF_LIBFDT 1 \#undef CONFIG_OF_FLAT_TREE \#define CONFIG_OF_BOARD_SETUP 1 \#define CONFIG_OF_HAS_BD_T 1 \#define CONFIG_OF_HAS_UBOOT_ENV 1 启动引导代码U-Boot 在完成自己的工作之后,会加载Linux 内核,并将扁平设备树的 地址传递给内核,其代码形式如下: \#if defined(CONFIG_OF_FLAT_TREE) || defined(CONFIG_OF_LIBFDT) if (of_flat_tree) { /* device tree; boot new style */ /* \* Linux Kernel Parameters (passing device tree): \* r3: pointer to the fdt, followed by the board info data \* r4: physical pointer to the kernel itself \* r5: NULL \* r6: NULL \* r7: NULL */ (*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0); /* does not return */ } \#endif
arch/powerpc 内核的入口有且只有一个,入口点为内核镜像的起始。此入口支持两种调
用方式,一种是支持Open Firmware 启动,另一种对于没有OF 的引导代码,需要使用扁平
设备树块,如上示例代码。寄存器r3 保存指向设备树的物理地址指针,寄存器r4 保存为内
核在物理内存中的地址,r5 为NULL。其中的隐含意思为:假设开启了mmu,那么这个mmu
的映射关系是1:1 的映射,即虚拟地址和物理地址是相同的。
7 Linux 内核对设备树的解析
扁平设备树描述了目标板平台中的设备树信息。每个设备都有一个节点来描述其信息,
每个节点又可以有子节点及其相应的属性。内核源码中include/linux/of.h 及drivers/of/base.c
等文件中提供了一些Open Firmware API,通过这些API,内核及设备驱动可以查找到相应
的设备节点,读取其属性值,利用这些信息正确地初始化和驱动硬件。
图2 内核及驱动对扁平设备树的解析
Fig2 Interaction from kernel and drivers with the FDT blob
8 结论
通过本文,你应该对Linux设备树dts移植有了一个基本的了解,它是一种描述和传递硬件配置信息的有效方式,可以适应嵌入式Linux系统的多样化需求。当然,设备树也不是一成不变的,它需要根据具体的硬件平台和内核版本进行定制和修改。总之,设备树是Linux系统中不可或缺的一个组件,值得你深入学习和掌握。
以上是Linux設備樹dts移植:如何描述和傳遞硬體配置訊息的詳細內容。更多資訊請關注PHP中文網其他相關文章!

linux设备节点是应用程序和设备驱动程序沟通的一个桥梁;设备节点被创建在“/dev”,是连接内核与用户层的枢纽,相当于硬盘的inode一样的东西,记录了硬件设备的位置和信息。设备节点使用户可以与内核进行硬件的沟通,读写设备以及其他的操作。

区别:1、open是UNIX系统调用函数,而fopen是ANSIC标准中的C语言库函数;2、open的移植性没fopen好;3、fopen只能操纵普通正规文件,而open可以操作普通文件、网络套接字等;4、open无缓冲,fopen有缓冲。

在linux中,可以利用“rpm -qa pcre”命令判断pcre是否安装;rpm命令专门用于管理各项套件,使用该命令后,若结果中出现pcre的版本信息,则表示pcre已经安装,若没有出现版本信息,则表示没有安装pcre。

端口映射又称端口转发,是指将外部主机的IP地址的端口映射到Intranet中的一台计算机,当用户访问外网IP的这个端口时,服务器自动将请求映射到对应局域网内部的机器上;可以通过使用动态或固定的公共网络IP路由ADSL宽带路由器来实现。

在linux中,eof是自定义终止符,是“END Of File”的缩写;因为是自定义的终止符,所以eof就不是固定的,可以随意的设置别名,linux中按“ctrl+d”就代表eof,eof一般会配合cat命令用于多行文本输出,指文件末尾。

linux查询mac地址的方法:1、打开系统,在桌面中点击鼠标右键,选择“打开终端”;2、在终端中,执行“ifconfig”命令,查看输出结果,在输出信息第四行中紧跟“ether”单词后的字符串就是mac地址。

手机远程linux工具有:1、JuiceSSH,是一款功能强大的安卓SSH客户端应用,可直接对linux服务进行管理;2、Termius,可以利用手机来连接Linux服务器;3、Termux,一个强大的远程终端工具;4、向日葵远程控制等等。

linux中,lsb是linux标准基础的意思,是“Linux Standards Base”的缩写,是linux标准化领域中的标准;lsb制定了应用程序与运行环境之间的二进制接口,保证了linux发行版与linux应用程序之间的良好结合。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。