5

IoT之嵌入式Linux设备树机制

 1 year ago
source link: https://www.51cto.com/article/740569.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

IoT之嵌入式Linux设备树机制

作者:移动Labs 2022-11-24 11:15:49
Linux内核v3.x之后提供了一个管理设备节点的机制,即设备树,其描述了硬件资源的板级信息。
c97831035a4f7493dee5753b826ae0a93e7fde.jpg

Part 01

●  Linux设备树机制的介绍  ● 

1.1 概念

设备树(device tree)是一种描述硬件资源的数据结构,起源于Open Firmware(OF:开源固件)。在Linux kernel v2.6之前的版本,关于ARM架构的板级硬件资源均通过.c和.h文件写“死”在arch/arm/plat-xxx和arch/arm/mach-xxx目录下,在开发一款设备时,Linux kernel中充斥着许多无用的硬件信息,不利于阅读和维护。在Linux ARM kernel v3.x之后正式引入设备树机制,主要是为减少这类无用的硬件板级信息被写入Linux kernel中污染内核,有了设备树,则可通过它来将所需的硬件信息传递给Linux kernel。

1.2 组成

设备树主要包含dts(device tree source,源文件)、dtc(device tree compiler,编译工具)和dtb(device tree blob,二进制文件)。

dts 是设备树描述的源文件,在ARM架构下,一个dts对应一个设备,一般位于arch/arm(64)/boot/dts目录下,该文件一般会有包含对应名称的.dtsi文件,类似于c语言的头文件,主要是一些SOC的宏定义共性部分。

dtc 是设备树的编译工具,类似于gcc等编译器,但与gcc不同的是dtc无需外部安装,是由内核自带的。可以将.dts文件编译成.dtb文件。

dtb 是设备树二进制文件,可被Linux kernel识别解析,也可被bootloader解析。

dtbo 是overlay编译出来的二进制文件。

dts、dtc和dtb三者间的关系如下图:

图片

Part 02

●  设备树框架和dts文件语法格式  ● 

2.1 设备树基本框架

设备树文件基本结构主要有以下几部分,其形式有点类似xml文件。

  • 单根节点(root):/
  • 节点名称:图中的"node1"和"node2"
  • 子节点:"child-node1"和"child-node2"
  • 节点地址:node@xxx
  • 属性(property):是一组键值对,包括属性名称(property name)和属性值(property value)
  • 标签(label,可选项)
图片

​https://elinux.org/Device_Tree_Usage#Basic_Data_Format​

值得注意的是,“/”是根节点,每个设备树文件仅有一个,当在设备树中发现有多个根节点时,在编译过程中这些根节点会合并成一个。

2.2 dts文件语法格式

与c语言类似,dts同样支持头文件,其头文件扩展名为.dtsi,一般通过#include xxx来引用。

例如,以全志H616这款芯片为例,基于Linux v4.9版本的orangepi开发板的时钟节点(部分)如下:

​/dts-v1/;
/memreserve/ 0x0000000048000000 0x0000000001000000;
/ {
interrupt-parent = <0x1>;
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "Orange Pi Zero 2";
compatible = "allwinner,h616", "arm,sun50iw9p1";
clocks {
compatible = "allwinner,clk-init";
device_type = "clocks";
#address-cells = <0x2>;
#size-cells = <0x2>;
ranges;
reg = <0x0 0x3001000 0x0 0x1000 0x0 0x7010000 0x0 0x400 0x0 0x7000000 0x0 0x4>;
};

上述中,特别重要的compatible属性,它可以以“,”格式指定名称的优先选择。设备树中每个代表设备的节点都要有一个compatible属性,它是OS用于决定绑定到设备驱动的关键特征。

Part 03

●  设备树的修改与内核编译安装 ● 

在编写模块的驱动程序时,为不影响内核结构,通常在外部目录下建立一个用于存放编写的驱动源码和编译生成的.ko的文件夹,生成的.ko可以在系统启动后单独加载运行,且无需和内核一起编译,方便更新。其流程一般为:makefile文件编写,接着进行驱动源码编写(可找优秀的架构进行修改,填充细节,如compatible,读、写操作等),然后编译生成.ko文件,进一步修改与单板相关的设备树文件(.dts),在.dts文件中添加或删除相应的设备节点信息,最后编译整个内核文件,当内核编译完成后,使用如下命令卸载旧版本的内核与安装新版本内核:

apt purge -y linux-image-xxx.deb // 卸载内核dpkg -i linux-image(dtb)-xxx.deb // 安装内核

重启单板后,用uname -a 命令查看内核信息,在新编译的内核上,用insmod 命令将生成的.ko模块加载上,cat 命令查看设备节点信息。

需要注意的是,设备树的使用需要在编译kernel时做好对应的配置,还需bootloader支持,否则也无法将数据结构传参给kernel。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK