Linux 设备树详解

1、概述

        设备树( Device Tree)是一种描述硬件的数据结构,在操作系统( OS)引导
阶段进行设备初始化的时候,数据结构中的硬件信息被检测并传递给操作系统
最早诞生于 Open Firmware, Flattened Device Tree (FDT)格式标准。
 dts 文件( Device Tree Source, dts)是以 ASCII 文本形式描述设备树内容。
 dtb 文件是二进制格式,编译工具为: Device Tree Compiler( DTC)。
 2011 年被引入 ARM Linux 内核。 ARM Linux 设备树描述了内核的软/硬件信息。

2、节点( node)和属性( property)

        节点用以归类描述一个硬件信息或是软件信息(好比文件系统的目录)
     节点内描述了一个或多个属性,属性是键值对( key/value),描述具体的
软/硬信息。
为什么 ARM Linux 社区会引入设备树呢?
    主要是想解决 ARM Linux 内核代码冗余的问题。

2.1、DTS 描述键值对的语法:


 1、字符串信息
 2、 32bits 无符号整型数组信息
 3、二进制数数组
 4、混和形式
 5、字符串哈希表

/dts-v1/;
#include "exynos4412.dtsi" //此设备树依赖于exynos4412.dtsi 文件
#include <dt-bindings/gpio/gpio.h> //gpio引脚配置文件
/ { //根节点 root node
    model = "FriendlyARM TINY4412 board based on Exynos4412";
    compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
    chosen {
    stdout-path = &serial_0;
};

2.2 节点语法规范说明

节点名:
语法: <name>[@<unit-address>]
规范:
名字是ASCII字符串
(字母、数字、 "-"、等等构成)
最长可以是31个字符一般的,应该以设备类型命名
unit-address一般的是设备地址
/*****示例*****/
/{
    serial@101F0000{
        ……
    };
    gpio@101F3000{
        ……
    };
    interrupt-controller@10140000{
        ……
    };
    spi@10115000{
        …….
    };
    external-bus{
        ……
    };
}; 

2.3节点名及节点路径

/{
    …
    dm9000{
        …
    };
    …
};
节点名:dm9000
节点路径:/dm9000

2.4 节点别名(节点引用)

    为了解决节点路径名过长的问题,引入了节点别名的概念,可以引用到一个全路径的节点

/{
    aliases{
        demo=&demo0;
    };
    …
    demo:demo0@80000000{
        …
    };
    …
};
节点名:demo0
节点路径:/demo0@80000000
节点别名:demo(等价/demo0@80000000)

/**********************************/
引用语法范例1:
&demo{
    …
};
引用语法范例2:
/{
    reference-node{
         property=<&demo>;
         …
    };
    …
};

2.5 合并节点内容

     一般的, 一个硬件设备的部分信息不会变化,但是部分信息是可能会变化的,就出现了节点内容合并。即:先编写好节点,仅仅描述部分属性值;使用者后加一部分属性值。在同级路径下,节点名相同的“两个”节点实际是一个节点。

 

/{
    node{
        property=value;
    };
};
/*移植者添加的节点*/
/{
    node{
        property2=value;
    };
};
/***合并后的节点内容***/
/{
    node{
        property2=value;
    };
};

2.6 替换节点内容

        一个硬件设备的部分属性信息可能会变化,但是设备树里面已经描述了所有的属性值,使用者可以添加已有的属性值,以替换原有的属性值,就出现了节点内容替换。在同级路径下,节点名相同的“两个”节点实际是一个节点。

2.7 引用节点内容

     一个设备可能会使用到别的节点的内容,可以通过节点的别名来引用到其内容。 引用的目的可能是合并两个节点的内容、 替换部分内容、或是使用部分内容.

/{
    node:node@80000000{
        property=value;
    };
};
/*移植者添加的node节点*/
&node{
    property=value;
        status = “okay”;
}
/*移植者添加demo节点*/
/{
    demo{
        property=<&node>;
    };
};
说明:demo节点的属性property引用了节点的node的属性值,一般的,引用的目的是使用node节点的部分属性内容

2.8 chosen 节点

     chosen 节点不描述一个真实设备,而是用于 firmware 传递一些数据给 OS,譬如 bootloader 传递内核启动参数给内核.

chosen {
    bootargs = “root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200”;
};

2.9 查找节点

   涉及设备、总线、驱动的概念,即所谓设备信息和驱动代码分离的驱动框架,如 platform、 i2c、 usb、spi、 pci、等等; 或是分层驱动框架( MTD 设备驱动、framebuffer 设备驱动、 input 设备驱动、 ...),则设备树中设备节点的会内核初始化时候被查找到,驱动代码将不关心节点的查找。
 如果仅仅是接口驱动框架(字符设备驱动、块设备驱动、网络设备驱动) ,则需要使用内核节点查找函数查找设备树中的设备节点。

2.10 查找办法


 通过节点的 compatible 属性值查找指定节点
 通过节点名查找指定节点
 通过节点路径查找指定节点

3 节点描述

头文件: include/of.h
struct device_node {
	const char *name; //节点名
	const char *type; //设备类型
	phandle phandle;
	const char *full_name; //全路径节点名
	struct fwnode_handle fwnode;
	struct  property *properties;
	struct  property *deadprops; /* removed properties */
	struct  device_node *parent; 父节点指针
	struct  device_node *child; //子节点指针
	struct  device_node *sibling;
	struct  kobject kobj;
	unsigned long _flags;
	void *data;
	#if defined(CONFIG_SPARC)
	const char *path_component_name;
	unsigned int unique_id;
	struct of_irq_controller *irq_trans;
	#endif
};

功能:通过 compatible 属性查找指定节点

struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
参数:
struct device_node *from - 指向开始路径的节点,如果为NULL,则从根节点开始
const char *type - device_type设备类型,可以为NULL
const char *compat - 指向节点的compatible属性的值(字符串)的首地址
返回值:
成功:得到节点的首地址;失败: NULL

设备 ID 表结构,用于匹配设备节点和驱动

struct of_device_id {
    char name[32]; /*设备名*/
    char type[32]; /*设备类型*/
    char compatible[128]; /*用于与设备树compatible属性值匹配的字符串*/
    const void *data; /*驱动私有数据*/
};
//注册支持设备树的设备ID表
include/module.h
MODULE_DEVICE_TABLE(of, ID表首地址)

功能:通过 compatible 属性查找指定节点

struct device_node *of_find_matching_node(struct device_node *from,
const struct of_device_id *matches);
参数:
struct device_node *from - 指向开始路径的节点,如果为NULL,则从根节点开始
const struct of_device_id *matches - 指向设备ID表,注意ID表必须以NULL结束
范例:
const struct of_device_id mydemo_of_match[] = {
	{ .compatible = "fs4412,mydemo", },
	{}
};
返回值:
成功:得到节点的首地址;失败: NULL

功能:通过路径查找指定节点

struct device_node *of_find_node_by_path(const char *path);
参数:
const char *path - 带全路径的节点名,也可以是节点的别名
返回值:
成功:得到节点的首地址;失败: NULL

功能:通过节点名查找指定节点

struct device_node *of_find_node_by_name(struct device_node *from,
const char *name);
参数:
struct device_node *from - 开始查找节点,如果为NULL,则从根节点开始
const char *name- 节点名
返回值:
成功:
得到节点的首地址;失败: NULL

 3.1 节点属性


有默认意义的属性
 1、设备树语法中已经定义好的,具有通用规范意义的属性。
 如果是设备信息和驱动分离框架的设备节点,则能够在内核初始化找到节点时候,自动解析生成相应的设备信息。
 常见属性的有: compatible、地址 address、中断 interrupt
 ARM Linux 内核定义好的,一类设备通用的有默认意义的属性
 一般的,不能被内核自动解析生成相应的设备信息,但是内核已经编写了相应的解析提取函数。
 常见属性的有: MAC 地址、 GPIO 口、 clock、 power、 regulator、等等

驱动自定义属性

针对具体设备,有部分属性很难通用,需要驱动自己定义好,通过内核的属性提取解析函数进行值的获得。

ethernet@18000000 {
	compatible = “davicom,dm9000”;
	reg = <0x18000000 0x2 0x18000004 0x2>;
	interrupt = <7 4>;
	local-mac-address = [00 00 de ad be ef];
	davicom,no-eeprom;
	reset-gpios = <&gpf 12 GPIO_ACTIVE_LOW>;
	vcc-supply = <&eth0_power>;
};

compatible 属性

用于匹配设备节点和设备驱动,规则是驱动设备 ID 表中的 compatible 域的值(字符串),和设备树中设备节点中的 compatible 属性值完全一致,则节点的内容是给驱动的。
 设备树中的命名规范如下

/{
node{
	compatible=“厂商名,名称” ;
		...
   
	    ...
    vcc-supply = <&eth0_power>;
};

设备树示例
/{
	…
	mydemo{
		compatible = “fs4412,mydemo”;
		…
	}
}

/*platform 框架的探测函数*/
static int demo_probe(struct platform_device *devices)
{
//设备树对应节点的信息已经被内核构造成struct platform_devic
…
}
static const struct of_device_id demo_of_matches[] = {
	{.compatible = “fs4412,mydemo”,},
	{}
}
MODULE_DEVICE_TABLE(of,demo_of_matches);
	static struct platform_driver demo_drv = {
		.driver = {
			.name = DEMONAME,
			.owner = THIS_MODULE,
			.of_match_table = of_match_ptr(demo_of)
		}
}

属性-address

#address-cells:描述子节点 reg 属性值的地址表中首地址 cell 数量
#size-cells:描述子节点 reg 属性值的地址表中地址长度 cell 数量

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

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

相关文章

【MySQL】:DDL数据库定义与操作

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; MySQL从入门到进阶 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. SQL的分类二. DDL数据库操作2.1 查询所有数据库2.2 查询当前数据库2.3 创建数…

测量鼠标DPI的三种方法,总有一种适合你

DPI(dots per inch)代表每英寸点数,是一种用于各种技术设备(包括打印机)的测量方法,但对于鼠标来说,指的是鼠标在桌面上移动1英寸的距离的同时,鼠标光标能够在屏幕上移动多少“点”。 许多游戏鼠标都有按钮,可以让你在玩游戏时动态切换DPI,但如果你不知道鼠标的DPI怎…

x-cmd pkg | duf - df 命令的现代化替代品

目录 简介用户首次快速实验指南技术特点竞品和相关作品进一步探索 简介 Duf &#xff08;Disk Usage/Free Utility&#xff09;是一个磁盘分析工具。其直观的输出和多样化的自定义选项&#xff0c;帮助用户更好地管理和优化存储资源。 用户首次快速实验指南 使用 x duf 即可自…

为什么大厂暴力裁员确很少有技术人敢举报?

最近几年大厂暴力裁员的事件太多了&#xff0c;但是确鲜有当事人出来举报&#xff0c;这个又是为什么呢&#xff1f;本文从中立的角度&#xff0c;来给大家来分析一下。 大厂会包装&#xff0c;将暴力裁员包装为KPI优化 KPI这个玩意&#xff0c;其实是蛮扯淡的&#xff0c;也…

重磅!30余所985高校全面取消博士统考!

2024年博士招生&#xff0c;又有“双一流”高校取消统考。 近日&#xff0c;各大高校正在陆续发布《2024年博士研究生招生简章》&#xff0c;其中南昌大学的博士招生方式引起了广泛关注。据悉&#xff0c;南昌大学将全面实行“申请—考核”制选拔方式&#xff0c;适用于直接攻…

【Linux】自定义shell

👑作者主页:@安 度 因 🏠学习社区:安度因 📖专栏链接:Linux 文章目录 获取命令行前置字段命令行输入解析命令行普通指令的执行子进程执行命令指令类型判断 && 内建命令总结 &&a

什么是OV证书?

OV证书是一种经过严格身份验证的SSL/TLS证书&#xff0c;相较于基础的域名验证(DV)证书&#xff0c;它的验证过程更为深入和全面。在颁发OV证书前&#xff0c;证书颁发机构(CA)不仅会验证申请者对域名的所有权&#xff0c;还会对企业或组织的身份进行严格的审查&#xff0c;包括…

京东年度数据报告-2023全年度饮料十大热门品牌销量(销额)榜单

2023年度&#xff0c;饮料市场的销售相较去年呈下滑状态。根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;京东平台上饮料市场的年度销量约9100万&#xff0c;同比下滑约9%&#xff1b;销售额约53亿&#xff0c;同比下滑约3%。另外&#xff0c;天猫平台上饮料市场的年度…

上门按摩系统:科技与传统融合的新体验

在快节奏的现代生活中&#xff0c;人们越来越重视身心健康。传统的按摩方式虽然深受喜爱&#xff0c;却常因时间、地点的限制而无法满足需求。此时&#xff0c;上门按摩系统应运而生&#xff0c;将科技与传统的按摩技艺完美结合&#xff0c;为用户提供更便捷、个性化的服务。 上…

基于SSM的流浪动物救助网站的设计与实现-计算机毕业设计源码82131

摘 要 随着生活水平的持续提高和家庭规模的缩小&#xff0c;宠物已经成为越来越多都市人生活的一部分&#xff0c;随着宠物的增多&#xff0c;流浪的动物的日益增多&#xff0c;中国的流浪动物领养和救助也随之形成规模&#xff0c;同时展现巨大潜力。本次系统的是基于SSM框架的…

使用Sqoop的并行处理:扩展数据传输

使用Sqoop的并行处理是在大数据环境中高效传输数据的关键。它可以显著减少数据传输的时间&#xff0c;并充分利用集群资源。本文将深入探讨Sqoop的并行处理能力&#xff0c;提供详细的示例代码&#xff0c;以帮助大家更全面地了解和应用这一技术。 Sqoop的并行处理 在开始介绍…

Java工具类——json字符串格式化处理

在我们拿到一团未经格式化的json字符串时&#xff0c;非常不方便查看&#xff0c;比如这样 {"APP_HEAD": {"TOTAL_NUM": "-1","PGUP_OR_PGDN": "0"},"SYS_HEAD": {"RET": [{"RET_CODE": &qu…

Puppeteer让你网页操作更简单(2)抓取数据

Puppeteer让你网页操作更简单(1)屏幕截图】 示例2 —— 让我们抓取一些数据 现在您已经了解了Headless Chrome和Puppeteer的工作原理基础知识,让我们看一个更复杂的示例,其中我们实际上可以抓取一些数据。 首先,请查看此处的Puppeteer API文档。如您所见,有大量不同的方法我…

el-select中多选回显数据后没法重新选择和更改

<el-form-item label"展示内容" prop"videoId"><el-select class"modal-input" multiple v-model"form.videoId"><el-optionclass"modal-input"v-for"(item) in videoIdTypes":key"item.id&q…

直播产品痛点话术

一、用户需求分析 为了更好地满足用户需求&#xff0c;我们对市场进行了深入的调研。发现主播们在直播过程中面临着多方面的挑战&#xff0c;如产品功能、质量、价格、安全性等方面的需求。 二、产品功能不足 当前市场上的主播产品存在功能不足的问题。例如&#xff0c;一些…

法规更新美国玩具标准ASTM F963-17有更新,最新标准为ASTM F963-23

美国材料试验协会 (ASTM)在10月13日发布了新的玩具安全标准&#xff1a;ASTM F963-23&#xff0c;ASTM F963-17美国联邦法规16 CFR 1250还在使用当中&#xff0c;出口美国的玩具的厂商要引起重视。 ASTM F963-17是什么标准&#xff1f; ASTM F963-17是美国玩具检测标准&#…

postman 简单测试(一)

1.postman官网 Postman API Platform 2.研究了一下postman 一些简单的功能&#xff0c;自己做个记录&#xff0c;同时希望能节约点测试时间。 2.1新建一个 collections 长期测的话&#xff0c;最好注册一个账号&#xff0c;开放更多功能。 2.2新建一个请求 后端要先搭建起来…

网络部署实战具体学习内容总结

网络部署实战具体学习内容总结 &#x1f4bb;网络部署实战课程通常旨在教授学生如何规划、配置、维护和优化计算机网络。这些课程涵盖了广泛的主题&#xff0c;以确保学生具备网络部署和管理所需的技能。 网络部署实战课程具体学习内容&#x1f447; 1️⃣网络架构设计及网络原…

解决方案:reactNative通过webview跳转微信智能客服空白webview页面

在reactNative中使用webview跳转微信智能客服&#xff0c;功能正常&#xff0c;从微信退回到App时&#xff0c;会有一个空白的webview页面&#xff0c;在使用感觉上不是那么的顺滑。解决这个可以在webview中使用onLoadEnd方法来解决这个问题 在react-native-webview中onLoadEn…

07-微服务getaway网关详解

一、初识网关 在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话会产生很多问题&#xff0c;例…