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

Linux驱动学习笔记(十)

热插拔

1.热插拔:就是带电插拔,即允许用户在不关闭系统,不切断电源的情况下拆卸或安装硬盘,板卡等设备。热插拔是内核和用户空间之间,通过调用用户空间程序实现交互来实现的,当内核发生了某种热拔插事件时,内核就会调用用户空间的程序来实现交互。热插拔机制有devfs、udev和mdev,devfs如今已经不再使用。嵌入式设备上一般使用mdev,X86上一般用udev,当然嵌入式设备上也可以用udev,mdev是udev的简化版本。udev是基于netlink机制实现的,通过udevd守护进程监听内核发送的uevent事件来执行相应的热插拔操作。而mdev是基于uevent helper机制,内核产生的uevent会调用uevent_helper所指的用户程序medv来执行热拔插动作。

2.int kobject_uevent(struct kobject *kobj, enum kobject_action action);函数可用来在内核中向用户空间发送设备事件通知uevent,触发用户态的udev/mdev等设备管理工具响应设备状态变化,该函数执行成功返回0。其中,kobj是关联的内核对象指针,代表触发事件的设备或子系统;action是发生的事件类型,包括下图所示的几种事件:

udevadm是Linux系统中用于管理和调试udev设备管理器的核心命令行工具,它允许用户直接与udev交互,查询设备信息、触发事件、监控设备变动或调试规则。使用方法为:

例如可以使用udevadm monitor命令监听所有内核设备事件,示例如下:

kobject_uevent函数向用户态发送事件时会调用kobject_uevent_env函数,如下图:

kobject_uevent_env函数可用来发送带有环境变量数据的事件。kobject_uevent_env函数会根据事件的类型进行对应的操作,但是这一流程是借助kset来实现的(uevent是通过netlink socket发送给用户空间的应用程序的,而netlink socket是基于kset的),所以发送事件的kobject必须属于某个kset,否则会导致事件发送失败,如下图:

如上图所示,在获取到发送事件的kobject所属的kset以及该kset的事件操作uevent_ops后,kobject_uevent_env函数依次执行这些操作,如下图:

最终kobject_uevent_env函数会广播要发送的事件,以便用户空间的应用程序可以接收并处理这些事件(对应udev)。另外如果定义了CONFIG_UEVENT_HELPER则会调用用户空间的uevent_helper程序(可将其设置成mdev)来处理uevent事件,如下图:

3.kset->uevent_ops中定义了三个函数,如下图:

其中,filter函数用于过滤,即当一个kobject想要向用户空间发送uevent时,由filter函数决定这个uevent是否应该被发送;name函数用于为uevent生成一个特定的名称字符串,这个名称会被添加到uevent的环境变量中,帮助用户空间应用程序识别事件来源;uevent函数来填充或修改发送到用户空间的uevent消息中的环境变量。一个示例如下图:

4.Linux提供了多种方式实现内核和用户空间的数据交换,比如系统调用、sysfs等,但是这些通信机制均为单工通信机制。而netlink是基于socket通信机制,具有双工通信的特点,可以很好的满足内核和用户空间的数据交换。因为netlink是基于socket通信机制,所以需要在用户空间使用socket接口实现。首先介绍几个函数:

  • int socket(int domain, int type, int protocol):用于创建套接字。其中domain表示所用协议,使用netlink机制时将其设置为AF_NETLINK;type表示套接字的类型,指定通信的方式和特性,使用netlink机制时将其设置为SOCK_RAW;protocol表示套接字使用的协议,通常设置为0,让系统自动选择适当的协议,在接收uevent时可将其设置为NETLINK_KOBJECT_UEVENT;该函数调用成功返回创建的套接字对应的文件描述符,失败返回-1并设置errno
  • int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen):用于将创建的套接字与指定的地址结构绑定。其中sockfd为套接字对应的文件描述符;addr为传入参数,在接收uevent时通常使用sockaddr_nl结构体(强转为sockaddr类型),这个结构体成员包括协议族(这里应为AF_NETLINK),当前进程PID;addrlen为addr的长度;该函数绑定成功返回0,失败返回-1并设置errno
  • ssize_t recv(int sockfd, void *buf, size_t len, int flags):用于接收内核发出的uevent事件。注意与一般网络编程不同,在netlink中是不用调用listen函数的,可以直接使用recv函数进行接收。其中sockfd为套接字对应的文件描述符;buf指向接收数据的缓冲区;len指定要读取的数据的字节数;flags指定一些标志用于控制如何接收数据,通常设置为0;成功情况下该函数返回实际读取到的字节数

netlink需要在用户空间循环读取内核发来的uevent,下图是一个例子(可参考讯为Linux驱动视频第十期P5):

5.对于uevent helper机制,要想在kobject_uevent_env函数中调用用户空间的uevent_helper程序来处理uevent事件,则需要定义CONFIG_UEVENT_HELPER,并且需要定义uevent_helper的路径(即CONFIG_UEVENT_HELPER_PATH的值),如下图:

有以下几种配置方法(可参考讯为Linux驱动视频第十期P6):

  • 在编译内核时直接配置CONFIG_UEVENT_HELPER_PATH:make menuconfig打开图形化配置界面后,选中Device Drivers->Generic Driver Options->Support for uevent helper后配置path to uevent helper,即配置uevent_helper的路径(例如可将其设置为/sbin/mdev)
  • make menuconfig打开图形化配置界面后,依次选中:Device Drivers->Generic Driver Options->Support for uevent helper(这一步是打开宏定义CONFIG_UEVENT_HELPER)、File systems->Pseudo fllesystems->/proc file system support、File systems->Pseudo fllesystems-> Sysctl support(/proc/sys)、Networking support。选中上述几个配置之后,就可以通过命令echo /sbin/mdev > /sys/kernel/uevent_helper对uevent_helper进行设置,或通过命令echo /sbin/mdev > /proc/sys/kernel/hotplug对uevent_helper进行设置(这两种设置方法实际就是通过对属性文件进行读写实现的)

一个简单的mdev程序如下图所示(可参考讯为Linux驱动视频第十期P7):

需要注意的是,kobject_uevent_env函数中调用的call_usermodehelper_exec函数是一个在内核空间中调用用户空间程序的函数,该函数执行用户空间程序时,将其作为子进程运行,并将其标准输入、标准输出和标准错误输出重定向到相应的文件描迷符。因此如果在用户空间程序中使用printf打印信息,这些信息将被输出到标准输出文件描述符(文件描述符1),而不是终端。因此需要在调用call_usermodehelper_exec时将标准输出重定向到终端,这样才可以在终端上看到printf输出的信息。

6.实现U盘热插拔的几个步骤,采用udev(可参考讯为Linux驱动视频第十期P8):

  • 首先需要在编译源码时配置所使用的Linux系统支持udev,例如对于buildroot文件系统,执行make menuconfig之后将System configuration->/dev management设置为Dynamic using devtmpfs + eudev表示使用udev
  • 启动系统后在/etc/udev/rules.d/目录下创建一个001.rules文件(若没有rules.d/目录则创建),其中001表示第一个规则文件,.rules是固定后缀。向在001.rules文件写入以下内容:
    KERNEL=="sd[a-z][0-9]",SUBSYSTEM=="block",ACTION=="add",RUN+="/etc/udev/rules.d/usb/usb-add.sh %k"
    SUBSYSTEM=="block",ACTION=="remove",RUN+="/etc/udev/rules.d/usb/usb-remove.sh"
    第一行表示当新增一个usb设备,执行/etc/udev/rules.d/usb/usb-add.sh脚本文件,并传入参数sd[a-z][0-9],第二行表示当移除一个usb设备,执行/etc/udev/rules.d/usb/usb-remove.sh脚本文件
  • 分别创建/etc/udev/rules.d/usb/usb-add.sh和/etc/udev/rules.d/usb/usb-remove.sh文件,分别写入以下内容:
    #!/bin/sh/bin/mount -t vfat /dev/$1 /mnt
    sync
    #!/bin/shsync
    /bin/unmount -l /mnt

还可以在/lib/udev/rules.d/目录下创建规则文件,但是/etc/udev/rules.d/比/lib/udev/rules.d的优先级高。TF卡的udev热插拔实现方式和U盘类似,只是U盘的节点名格式为sd[a-z][0-9],而TF卡的节点名格式为mmcblk[0-9]p[0-9]。采用mdev实现U盘和TF卡的热插拔步骤与udev类似,可参考讯为Linux驱动视频第十期P10、P11。

7.USBmount是一个用于自动挂载USB存储设备的工具,它可以在Linux系统中自动挂载插入的USB存储设备并在设备拔出时自动卸载。USBmount的工作原理是通过udev监视USB设备的插拔事件,并在检测到设备插入时自动挂载设备,检测到设备拔出时自动卸载设备。USBmount不需要手动挂载或卸载USB存储设备,因此可以方便地在嵌入式系统中使用(USBmount使用方式可参考讯为Linux驱动视频第十期P12)。

相关文章:

Linux驱动学习笔记(十)

热插拔 1.热插拔:就是带电插拔,即允许用户在不关闭系统,不切断电源的情况下拆卸或安装硬盘,板卡等设备。热插拔是内核和用户空间之间,通过调用用户空间程序实现交互来实现的,当内核发生了某种热拔插事件时…...

如何优化Elasticsearch的搜索性能?

优化 Elasticsearch 的搜索性能需要从索引设计、查询优化、硬件配置和集群调优等多方面入手。以下是系统化的优化策略和实操建议: 一、索引设计优化 1. 合理设置分片数 分片大小:单个分片建议 10-50GB(超过50GB会影响查询性能)。分片数量: 总分片数 ≤ 节点数 1000(避免…...

TI dsp FSI (快速串行接口)

简介 快速串行接口(FSI - Fast Serial Interface )模块是一种串行通信外设,能够在隔离设备之间实现可靠的高速通信。在两个没有共同电源和接地连接的电子电路必须交换信息的情况下,电气隔离设备被使用。 虽然隔离设备促进了信号通…...

责任链模式:构建灵活可扩展的请求处理体系(Java 实现详解)

一、责任链模式核心概念解析 (一)模式定义与本质 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,其核心思想是将多个处理者对象连成一条链,并沿着这条链传递请求,直到有某…...

nlp中的频率就是权重吗

🔢 一、“频率”是什么? 在 NLP 中,**词频(frequency)**通常指的是: 某个单词或 token 在语料库中出现的次数(或比例) 举例: "The cat sat on the mat. The cat i…...

融智学“新五常”框架:五维方式的重构与协同

融智学“新五常”框架:五维方式的重构与协同 一、理论基底:从传统老五常到当代新五常的范式跃迁 邹晓辉教授提出的新五常(生活方式DBA、学习方式DBA、工作方式DBA、旅行方式DBA、娱乐方式DBA),本质是将融智学的核心原…...

wechat-003-学习笔记

1.路由跳转页面:携带的参数会出现在onlaod中的options中。 注意:原生小程序对路由传参的长度也有限制,过长会被截掉。 2.wx.setNavigationBarTitle(Object object) 动态设置当前页面的标题 3.在根目录中的app.json文件中配置 后台播放音乐的能…...

【大模型微调】魔搭社区GPU进行LLaMA-Factory微调大模型自我认知

文章概要: 本文是一篇详细的技术教程,介绍如何使用魔搭社区(ModelScope)的GPU资源来进行LLaMA-Factory的模型微调。文章分为11个主要步骤,从环境准备到最终的模型测试,系统地介绍了整个微调流程。主要内容包…...

基于MATLAB编程针对NCV检测数据去漂移任务的完整解决方案

以下为针对NCV检测数据去漂移任务的完整解决方案,基于MATLAB编程实现,结构清晰,内容详实,满足技术深度。 NCV信号尾部漂移处理与分析 1. 任务背景与目标 神经传导速度(NCV)检测信号易受环境干扰与设备漂移…...

【数据结构】哈希表的实现

文章目录 1. 哈希的介绍1.1 直接定址法1.2 哈希冲突1.3 负载因子1.4 哈希函数1.4.1 除法散列法/除留余数法1.4.2 乘法散列法1.4.3 全域散列法 1.5 处理哈希冲突1.5.1 开放地址法1.5.1.1 线性探测1.5.1.2 二次探测1.5.1.3 双重探测1.5.1.4 三种探测方法对比 1.6.3 链地址法 2. 哈…...

永磁同步电机控制算法--基于电磁转矩反馈补偿的新型IP调节器

一、基本原理 先给出IP速度控制器还是PI速度控制器的传递函数: PI调节器 IP调节器 从IP速度控制器还是PI速度控制器的传递函数可以看出,系统的抗负载转矩扰动能力相同,因此虽然采用IP速度控制器改善了转速环的超调问题,但仍然需要通过其他途…...

RabbitMQ 应用 - SpringBoot

以下介绍的是基于 SpringBoot 的 RabbitMQ 开发介绍 Spring Spring AMQP RabbitMQ RabbitMQ tutorial - "Hello World!" | RabbitMQ 工程搭建步骤: 1.引入依赖 2.编写 yml 配置,配置基本信息 3.编写生产者代码 4.编写消费者代码 定义监听类,使用 RabbitListener…...

基于递归思想的系统架构图自动化生成实践

文章目录 一、核心思想解析二、关键技术实现1. 动态布局算法2. 样式规范集成3. MCP服务封装三、典型应用场景四、最佳实践建议五、扩展方向一、核心思想解析 本系统通过递归算法实现了Markdown层级结构到PPTX架构图的自动转换,其核心设计思想包含两个维度: 数据结构递归:将…...

OpenGL Chan视频学习-9 Index Buffers inOpenGL

bilibili视频链接: 【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p5&vd_source44b77bde056381262ee55e448b9b1973 函数网站: docs.gl 说明: 1.之后就不再单独整理网站具体函数了,网站直接翻译会…...

《基于AIGC的智能化多栈开发新模式》研究报告重磅发布! ——AI重塑软件工程,多栈开发引领未来

在人工智能技术迅猛发展的浪潮下,软件开发领域正经历一场前所未有的范式革命。在此背景下,由贝壳找房(北京)科技有限公司、中国信息通信研究院云计算与大数据研究所联合编写,阿里、腾讯、北京大学、南京大学、同济大学…...

热门大型语言模型(LLM)应用开发框架

我们来深入探索这些强大的大型语言模型(LLM)应用开发框架,并且我会尝试用文本形式描述一些核心的流程图,帮助您更好地理解它们的工作机制。由于我无法直接生成图片,我会用文字清晰地描述流程图的各个步骤和连接。 Lang…...

Nginx安全防护与HTTPS部署实战

目录 前言一. 核心安全配置1. 隐藏版本号2. 限制危险请求方法3. 请求限制(CC攻击防御)(1)使用nginx的limit_req模块限制请求速率(2)压力测试验证 4. 防盗链 二. 高级防护1. 动态黑名单(1&#x…...

JAVA重症监护系统源码 ICU重症监护系统源码 智慧医院重症监护系统源码

智慧医院重症监护系统源码 ICU重症监护系统源码 开发语言:JavaVUE ICU护理记录:实现病人数据的自动采集,实时记录监护过程数据。支持主流厂家的监护仪、呼吸机等床旁数字化设备的数据采集。对接检验检查系统,实现自动化录入。喜…...

静态资源js,css免费CDN服务比较

静态资源js,css免费CDN服务比较 分析的 CDN 服务列表: BootCDN (https://cdn.bootcdn.net/ajax/libs)jsDelivr (主域名) (https://cdn.jsdelivr.net/npm)jsDelivr (Gcore 镜像) (https://gcore.jsdelivr.net/npm)UNPKG (https://unpkg.com)ESM (https://esm.sh)By…...

组合型回溯+剪枝

本篇基于b站灵茶山艾府。 77. 组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2&#…...

python:机器学习(KNN算法)

本文目录: 一、K-近邻算法思想二、KNN的应用方式( 一)分类流程(二)回归流程 三、API介绍(一)分类预测操作(二)回归预测操作 四、距离度量方法(一)…...

【笔记】2025 年 Windows 系统下 abu 量化交易库部署与适配指南

#工作记录 前言 在量化交易的学习探索中,偶然接触到 2017 年开源的 abu 量化交易库,其代码结构和思路对新手理解量化回测、指标分析等基础逻辑有一定参考价值。然而,当尝试在 2025 年的开发环境中部署这个久未更新的项目时,遇到…...

小程序 - 视图与逻辑

个人简介 👨‍💻‍个人主页: 魔术师 📖学习方向: 主攻前端方向,正逐渐往全栈发展 🚴个人状态: 研发工程师,现效力于政务服务网事业 🇨🇳人生格言: “心有多大,舞台就有多大。” 📚推荐学习: 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒T…...

ChatGPT Plus/Pro 订阅教程(支持支付宝)

订阅 ChatGPT Plus GPT-4 最简单,成功率最高的方案 1. 登录 chat.openai.com 依次点击 Login ,输入邮箱和密码 2. 点击升级 Upgrade 登录自己的 OpenAI 帐户后,点击左下角的 Upgrade to Plus,在弹窗中选择 Upgrade plan。 如果…...

[蓝帽杯 2022 初赛]网站取证_2

一、找到与数据库有关系的PHP文件 打开内容如下,发现数据库密码是函数my_encrypt()返回的结果。 二、在文件夹encrypt中找到encrypt.php,内容如下,其中mcrypt已不再使用,所以使用php>7版本可能没有执行结果,需要换成较低版本…...

vue3+Pinia+element-plus 后台管理系统项目实战记录

vue3Piniaelement-plus 后台管理系统项目实战记录 参考项目:https://www.bilibili.com/video/BV1L24y1n7tB 全局api provide、inject vue2 import api from/api vue.propotype.$api apithis.$api.xxxvue3 import api from/api app.provide($api, api)import {…...

安装 Node.js 和配置 cnpm 镜像源

一、安装 Node.js 方式一:官网下载(适合所有系统) 访问 Node.js 官网 推荐选择 LTS(长期支持)版本,点击下载安装包。 根据系统提示一步步完成安装。 方式二:通过包管理器安装(建…...

MacOS内存管理-删除冗余系统数据System Data

文章目录 一、问题复现二、解决思路三、解决流程四、附录 一、问题复现 以题主的的 Mac 为例,我们可以看到System Data所占数据高达77.08GB,远远超出系统所占内存 二、解决思路 占据大量空间的是分散在系统中各个位置Cache数据; 其中容量最…...

电脑开机后长时间黑屏,桌面图标和任务栏很久才会出现,但是可通过任务管理器打开应用程序,如何解决

目录 一、造成这种情况的主要原因(详细分析): (1)启动项过多,导致系统资源占用过高(最常见) 检测方法: (2)系统服务启动异常(常见&a…...

行为型:中介者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 5、注意事项 1、核心思想 目的:通过引入一个中介对象来封装一组对象之间的交互,解决对象间过度耦合、频繁交互的问题。不管是对象引用维护还是消息的转发&am…...