当前位置: 首页 > news >正文

Linux驱动开发—设备树传递给内核,匹配驱动过程分析

文章目录

    • 总体流程图
    • 传递DTB过程
      • 编译设备树源文件
      • 将 `.dtb` 文件与内核或引导加载程序集成
    • 内核初始化阶段解析DTB
      • 内核启动阶段
      • 解析 DTB
      • 注册设备树节点
      • 驱动程序绑定

内核解析设备树二进制文件(DTB)的过程主要分为几个步骤,从设备树的传递到最终的硬件配置。这些步骤包括加载 DTB、解析和处理设备树节点和属性,以及将硬件信息传递给相应的驱动程序。

总体流程图

在这里插入图片描述

传递DTB过程

在系统启动时,引导加载程序(如 U-Boot)将 DTB 文件加载到内存,并将其位置传递给内核。对于 ARM 和 ARM64 平台,引导加载程序通常通过 r2 寄存器传递 DTB 的内存地址。

编译设备树源文件

设备树源文件(.dts)需要编译成设备树二进制文件(.dtb):

dtc -I dts -O dtb -o my_device_tree.dtb my_device_tree.dts

.dtb 文件与内核或引导加载程序集成

a. 将 .dtb 文件与内核镜像一起打包

在一些平台上,.dtb 文件被包含在内核镜像中。这通常通过内核构建系统中的配置来完成。例如,在 arm 平台上,可以通过以下步骤进行配置:

  • 确保内核配置中启用了设备树支持(CONFIG_OF)。
  • 将设备树二进制文件指定为内核构建的一部分,通常通过内核的 MakefileKconfig 文件。

b. 通过引导加载程序加载设备树

引导加载程序(例如 U-Boot)负责加载内核,并在加载内核之前传递设备树:

  1. 引导加载程序首先加载设备树二进制文件(.dtb)。
  2. 然后,引导加载程序将设备树传递给内核。

在 U-Boot 中,这通常通过设置环境变量来实现:

setenv fdtfile my_device_tree.dtb
load mmc 0:1 ${fdt_addr} ${fdtfile}
bootz ${kernel_addr} - ${fdt_addr}

fdtfile 是设备树二进制文件的路径。

fdt_addr 是设备树加载到内存中的地址。

kernel_addr 是内核镜像的地址。

当内核启动时,它会从引导加载程序接收设备树

内核初始化阶段解析DTB

内核解析设备树二进制文件(DTB)的过程主要分为几个步骤,从设备树的传递到最终的硬件配置。这些步骤包括加载 DTB、解析和处理设备树节点和属性,以及将硬件信息传递给相应的驱动程序

内核启动阶段

内核启动时,会在启动代码中处理传递过来的 DTB 地址,并将其保存在全局变量中。以 ARM64 为例,启动代码会保存 DTB 地址,并在后续初始化过程中使用:

void __init setup_arch(char **cmdline_p)
{// 保存 DTB 地址initial_boot_params = __va(FDT_START);
}

解析 DTB

内核在初始化过程中会调用设备树相关的函数来解析 DTB。主要函数如下:

a. 在imx_4.14.98_2.0.0_ga/arch/arm64/kernel 中setup.c 中early_init_dt_scan()

static void __init setup_machine_fdt(phys_addr_t dt_phys)
{void *dt_virt = fixmap_remap_fdt(dt_phys);const char *name;if (!dt_virt || !early_init_dt_scan(dt_virt)) {pr_crit("\n""Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n""The dtb must be 8-byte aligned and must not exceed 2 MB in size\n""\nPlease check your bootloader.",&dt_phys, dt_virt);while (true)cpu_relax();}name = of_flat_dt_get_machine_name();if (!name)return;pr_info("Machine model: %s\n", name);dump_stack_set_arch_desc("%s (DT)", name);
}

内核首先调用 early_init_dt_scan() 来扫描和验证设备树的基本结构、总大小和根节点:

void __init early_init_dt_scan(void *params)
{if (fdt_check_header(params))panic("Invalid device tree blob");// 解析根节点和基本属性early_init_dt_verify(params);early_init_dt_reserve_memory();unflatten_device_tree();
}

b.在drivers/of/fdt.c 中定义了如何解析为树状结构函数 : unflatten_device_tree()

unflatten_device_tree() 函数将设备树的扁平结构转换为内核使用的树形结构:

/*** __unflatten_device_tree - create tree of device_nodes from flat blob** unflattens a device-tree, creating the* tree of struct device_node. It also fills the "name" and "type"* pointers of the nodes so the normal device-tree walking functions* can be used.* @blob: The blob to expand* @dad: Parent device node* @mynodes: The device_node tree created by the call* @dt_alloc: An allocator that provides a virtual address to memory* for the resulting tree** Returns NULL on failure or the memory chunk containing the unflattened* device tree on success.*/
void *__unflatten_device_tree(const void *blob,struct device_node *dad,struct device_node **mynodes,void *(*dt_alloc)(u64 size, u64 align),bool detached)
{int size;void *mem;pr_debug(" -> unflatten_device_tree()\n");if (!blob) {pr_debug("No device tree pointer\n");return NULL;}pr_debug("Unflattening device tree:\n");pr_debug("magic: %08x\n", fdt_magic(blob));pr_debug("size: %08x\n", fdt_totalsize(blob));pr_debug("version: %08x\n", fdt_version(blob));if (fdt_check_header(blob)) {pr_err("Invalid device tree blob header\n");return NULL;}/* First pass, scan for size */size = unflatten_dt_nodes(blob, NULL, dad, NULL);if (size < 0)return NULL;size = ALIGN(size, 4);pr_debug("  size is %d, allocating...\n", size);/* Allocate memory for the expanded device tree */mem = dt_alloc(size + 4, __alignof__(struct device_node));if (!mem)return NULL;memset(mem, 0, size);*(__be32 *)(mem + size) = cpu_to_be32(0xdeadbeef);pr_debug("  unflattening %p...\n", mem);/* Second pass, do actual unflattening */unflatten_dt_nodes(blob, mem, dad, mynodes);if (be32_to_cpup(mem + size) != 0xdeadbeef)pr_warning("End of tree marker overwritten: %08x\n",be32_to_cpup(mem + size));if (detached && mynodes) {of_node_set_flag(*mynodes, OF_DETACHED);pr_debug("unflattened tree is detached\n");}pr_debug(" <- unflatten_device_tree()\n");return mem;
}

c. early_init_dt_scan_nodes()

这个函数扫描设备树的所有节点,并将其转换为内核中的数据结构:

void __init early_init_dt_scan_nodes(void)
{/* Retrieve various information from the /chosen node */of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);/* Initialize {size,address}-cells info */of_scan_flat_dt(early_init_dt_scan_root, NULL);/* Setup memory, calling early_init_dt_add_memory_arch */of_scan_flat_dt(early_init_dt_scan_memory, NULL);
}

注册设备树节点

内核将解析的设备树节点注册到设备模型中,通常通过位于drivers/of/platform.c的 of_platform_populate() 函数完成:

int __init of_platform_populate(void)
{struct device_node *root;root = of_find_node_by_path("/");of_platform_default_populate(root, NULL, NULL);return 0;
}

驱动程序绑定

设备树解析后,内核会根据设备树中的信息来匹配相应的驱动程序,并进行设备初始化。驱动程序通常通过 of_match_table 表来匹配设备树中的节点

static const struct of_device_id my_driver_of_match[] = {{ .compatible = "my_vendor,my_device", },{ }
};
MODULE_DEVICE_TABLE(of, my_driver_of_match);

驱动程序通过 of_device 结构体访问设备树节点和属性:

static int my_driver_probe(struct platform_device *pdev)
{struct device_node *np = pdev->dev.of_node;// 读取属性并初始化设备return 0;
}

相关文章:

Linux驱动开发—设备树传递给内核,匹配驱动过程分析

文章目录 总体流程图传递DTB过程编译设备树源文件将 .dtb 文件与内核或引导加载程序集成 内核初始化阶段解析DTB内核启动阶段解析 DTB注册设备树节点驱动程序绑定 内核解析设备树二进制文件&#xff08;DTB&#xff09;的过程主要分为几个步骤&#xff0c;从设备树的传递到最终…...

深入理解 Go 语言信号量 Semaphore

1. 什么是信号量 信号量的概念是荷兰计算机科学家 Edsger Wybe Dijkstra 在 1963 年左右提出来的,被广泛应用在不同的操作系统中。在操作系统中,会给每一个进程分配一个信号量,代表每个进程目前的状态。未得到控制权的进程,会在特定的地方被迫停下来,等待可以继续进行的信…...

git——删除远程仓库中的文件或文件夹步骤图解(只是从远程仓库中删除,本地文件不受影响、不会被删除)

目录 一、删除远程仓库中的文件或文件夹1.1、 以删除远程仓库jetcache-demo项目中的logs文件夹为例1.2、 删除远程仓库jetcache-demo项目中的logs文件夹步骤图解 一、删除远程仓库中的文件或文件夹 1.1、 以删除远程仓库jetcache-demo项目中的logs文件夹为例 删除远程仓库jet…...

详解贪心算法

贪心算法&#xff08;Greedy Algorithm) 概述&#xff1a; 贪心算法是一种在求解最优化问题时采取的一种常用算法策略。贪心算法的基本思想是&#xff0c;每次选择当前情况下的局部最优解&#xff0c;并相信这个局部最优解能够导致全局最优解。贪心算法通过迭代的方式一步步地…...

LabVIEW工件表面瑕疵识别系统

开发了一种利用LabVIEW和IMAQ Vision视觉工具进行工件表面瑕疵识别的系统。该系统通过图像处理技术识别并分类工件表面的裂纹、划痕等缺陷&#xff0c;从而提升生产线的分拣效率和产品质量。 项目背景 工业生产中&#xff0c;工件表面的缺陷直接影响产品质量和生产效率。传统人…...

LabVIEW水下根石监测系统

开发了一种基于LabVIEW平台开发的水下根石监测系统。该系统利用高精度姿态传感器与位移传感器&#xff0c;实现了水下根石状态的实时自动监测&#xff0c;提高了水利工程安全管理的现代化和精细化水平&#xff0c;具有高精度、高稳定性和良好的操作性。 项目背景&#xff1a; …...

探索全光网技术 | 全光网络技术方案选型建议三(医院场景)

目录 一、场景设计需求二、医院场景拓扑三、部署方式四、产品相关规格说明五、方案优势与特点 注&#xff1a;本文章参考资料为&#xff1a;华三官方资料 - “新华三全光网络3.0解决方案&#xff08;教育&#xff09;”与 锐捷官方资料 - “【锐捷】高校极简以太全光3.X方案设计…...

【C++语言】vector迭代器与常见oj题

vector迭代器的失效问题 接上篇vector的介绍和使用中最后提到的vector迭代器&#xff0c;我们继续来看vector迭代器的失效问题。 以下代码的功能是删除vector中所有的偶数&#xff0c;请问那个代码是正确的&#xff0c;为什么&#xff1f; #include <iostream> using na…...

高职物联网智慧农业实训室建设方案

一、项目概述 随着物联网技术的迅猛发展及其在农业领域的广泛应用&#xff0c;智慧农业已经成为推动农业现代化的关键力量。近年来&#xff0c;国家高度重视物联网技术在农业领域的应用与发展&#xff0c;出台了一系列相关政策支持智慧农业建设。如《数字乡村发展战略纲要》明…...

Pytorch 高效快速加载大规模数据集

一、前言 最近遇到一个多模态学习任务,原始数据为HDF5 格式,遇到主要两个问题:一是数据量过大无法直接加载到内存,二是HDF5 是基于关键值索引,索引速度非常慢。在使用Pytorch 训练模型时,数据加载速度跟不上模型训练速度,导致GPU使用率低。阅读OLMO 框架关于数据集加载…...

Spring Boot集成protobuf快速入门Demo

1.什么是protobuf&#xff1f; Protobuf&#xff08;Protocol Buffers&#xff09;是由 Google 开发的一种轻量级、高效的数据交换格式&#xff0c;它被用于结构化数据的序列化、反序列化和传输。相比于 XML 和 JSON 等文本格式&#xff0c;Protobuf 具有更小的数据体积、更快…...

SpringBoot+Vue 简单小文章项目开发全过程

文章目录 一、项目介绍二、需求设计三、数据库设计四、项目构建项目技术选型:构建项目说明:项目架构mavenMySQLRedis 五、项目开发&#xff1a;项目开发思路&#xff1a;项目开发过程&#xff1a;1. 导入文件包/新建项目2. 新建子模块&#xff1a;common模块pojo模块server模块…...

如何将发明原理应用于产品设计的概念阶段?

众所周知&#xff0c;产品设计的概念阶段是创意孵化的关键时期&#xff0c;它决定了产品的方向、定位及核心卖点。在这一阶段&#xff0c;将发明原理融入其中&#xff0c;能够极大地拓宽思维边界&#xff0c;激发前所未有的设计灵感。具体步骤如深圳天行健企业管理咨询公司下文…...

【wsl】wsl + vscode 中使用 typora 打开 markdown 文件

vscode 连接好wsl 使用Open in External App 一个五星好评的插件Open in External App则可以在vscode中用typora打开md文件&#xff0c;不仅如此&#xff0c;还有设定其他应用打开相应的文件&#xff0c;比如chrome打开html。插件食用方法也比较简单&#xff0c;安装后&#…...

AutoDL下huggingface下载模型位置问题

AutoDL系统盘只有30G&#xff0c;数据盘有50G且可扩容&#xff0c;模型及数据集空间通常较大&#xff0c;为节省系统盘空间&#xff0c;我们将文件都存储于数据盘&#xff0c;在运行的代码最前端&#xff08;一定要在最前面&#xff09;添加 import os os.environ[HF_HOME] /…...

SpringBoot基础(一):快速入门

SpringBoot基础系列文章 SpringBoot基础(一)&#xff1a;快速入门 目录 一、SpringBoot简介二、快速入门三、SpringBoot核心组件1、parent1.1、spring-boot-starter-parent1.2、spring-boot-dependencies 2、starter2.1、spring-boot-starter-web2.2、spring-boot-starter2.3、…...

使用Weka进行数据挖掘与机器学习

在当前大数据时代&#xff0c;数据挖掘与机器学习已经成为了不可或缺的技术。而Weka是一个非常流行的机器学习软件&#xff0c;它提供了一整套的机器学习算法和数据处理工具。Weka不仅支持命令行操作和GUI&#xff0c;还提供了Java API&#xff0c;非常适合Java开发者进行数据挖…...

定时器知识点

#视频教程&#xff1a; 11.TIM定时中断 CSDN教程 知识点&#xff1a; 1.时钟源选择图 ![[Pasted Image 20240802103525_114.png]] 基本定时器 2个功能 &#xff1a;只能定时中断和主模式触发DAC的功能 知识点 1.时基单元&#xff1a;预分配器&#xff08;PSC&#xff09;、…...

桌面日历还能这样玩?这个日历太酷了吧!秒变桌面记事本!

大家应该有经常看日历的习惯&#xff0c;每个人都有不同的日历需求。特别是一些节假日&#xff0c;重要节日时候&#xff0c;大家看日历的频次就比较高了&#xff0c;如何选一款好用的日历&#xff1f;我们给大家展示一款非常不错的桌面日历&#xff0c;看下你喜不喜欢&#xf…...

基于深度学习的太阳暗条检测(2020年以来)

A universal method for solar filament detection from Hα observations using semi-supervised deep learning A&A, 686, A213 (2024) A universal method for solar filament detection from Hα observations using semi-supervised deep learning (aanda.org) ABS…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...