linux 设备模型之设备驱动

设备模型跟踪所有对系统已知的驱动. 这个跟踪的主要原因是使驱动核心能匹配驱动和新
设备. 一旦驱动在系统中是已知的对象, 但是, 许多其他的事情变得有可能. 设备驱动可
输出和任何特定设备无关的信息和配置变量, 例如:

驱动由下列结构定义:
struct device_driver {
char *name;
struct bus_type *bus;
struct kobject kobj;
struct list_head devices;
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown) (struct device *dev);
};
再一次, 几个结构成员被忽略( 全部内容见 <linux/device.h> ). 这里, name 是驱动的
名子( 它在 sysfs 中出现 ), bus 是这个驱动使用的总线类型, kobj 是必然的 kobject,
devices 是当前绑定到这个驱动的所有设备的列表, probe 是一个函数被调用来查询一个
特定设备的存在(以及这个驱动是否可以使用它), remove 当设备从系统中去除时被调用,
shutdown 在关闭时被调用来关闭设备.
使用 device_driver 结构的函数的形式, 现在应当看来是类似的(因此我们快速涵盖它
们). 注册函数是:
int driver_register(struct device_driver *drv);
void driver_unregister(struct device_driver *drv);
通常的属性结构在:
struct driver_attribute {
struct attribute attr;

ssize_t (*show)(struct device_driver *drv, char *buf);
ssize_t (*store)(struct device_driver *drv, const char *buf,
size_t count);
};
DRIVER_ATTR(name, mode, show, store);
以及属性文件以通常的方法创建:
int driver_create_file(struct device_driver *drv, struct driver_attribute *attr);
void driver_remove_file(struct device_driver *drv, struct driver_attribute *attr);
bus_type 结构含有一个成员( drv_attrs ) 指向一套缺省属性, 对所有关联到这个总线
的驱动都创建.

 驱动结构嵌入

如同大部分驱动核心结构的情形, device_driver 结构常常被发现嵌到一个更高级的, 总
线特定的结构. lddbus 子系统不会和这样的趋势相反, 因此它已定义了它自己的
ldd_driver 结构:
struct ldd_driver {
char *version;
struct module *module;
struct device_driver driver;
struct driver_attribute version_attr;
};
#define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver);
这里, 我们要求每个驱动提供特定当前软件版本, 并且 lddbus 输出这个版本字串为它知
道的每个驱动. 总线特定的驱动注册函数是:
int register_ldd_driver(struct ldd_driver *driver)
{
int ret;
driver->driver.bus = &ldd_bus_type;
ret = driver_register(&driver->driver);
if (ret)
return ret;
driver->version_attr.attr.name = "version";
driver->version_attr.attr.owner = driver->module;
driver->version_attr.attr.mode = S_IRUGO;
driver->version_attr.show = show_version;
driver->version_attr.store = NULL;
return driver_create_file(&driver->driver, &driver->version_attr);
}
这个函数的第一部分只注册低级的 device_driver 结构到核心; 剩下的建立版本属性.
因为这个属性在运行时被创建, 我们不能使用 DRIVER_ATTR 宏; 反之,

driver_attribute 结构必须手工填充. 注意我们设定属性的拥有者为驱动模块, 不是
lddbus 模块; 这样做的理由是可以在为这个属性的 show 函数的实现中见到:
static ssize_t show_version(struct device_driver *driver, char *buf)
{
struct ldd_driver *ldriver = to_ldd_driver(driver);
sprintf(buf, "%s\n", ldriver->version);
return strlen(buf);
}
有人可能认为属性拥有者应当是 lddbus 模块, 因为实现这个属性的函数在那里定义. 这
个函数, 但是, 是使用驱动自身所创建的 ldd_driver 结构. 如果那个结构在一个用户空
间进程试图读取版本号时要消失, 事情会变得麻烦. 指定驱动模块作为属性的拥有者阻止
了模块被卸载, 在用户空间保持属性文件打开时. 因为每个驱动模块创建一个对 lddbus
模块的引用, 我们能确信 lddbus 不会在一个不合适的时间被卸载.
为完整起见, sculld 创建它的 ldd_driver 结构如下:
static struct ldd_driver sculld_driver = { .version = "$Revision: 1.1
$", .module = THIS_MODULE, .driver = { .name = "sculld", }, };
一个简单的对 register_ldd_driver 的调用添加它到系统中. 一旦完成初始化, 驱动信
息可在 sysfs 中见到:
$ tree /sys/bus/ldd/drivers
/sys/bus/ldd/drivers
`-- sculld
|-- sculld0 -> ../../../../devices/ldd0/sculld0
|-- sculld1 -> ../../../../devices/ldd0/sculld1
|-- sculld2 -> ../../../../devices/ldd0/sculld2
|-- sculld3 -> ../../../../devices/ldd0/sculld3
`-- version
[46]  这个总线的逻辑名子, 当然, 应当是"sbus", 但是这个名子已经被一个真实的, 物理总
线采用.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BigDecimal的性能问题

BigDecimal 是 Java 中用于精确计算的数字类&#xff0c;它可以处理任意精度的小数运算。由于其精确性和灵活性&#xff0c;BigDecimal 在某些场景下可能会带来性能问题。 BigDecimal的性能问题 BigDecimal的性能问题主要源于以下几点&#xff1a; 内存占用&#xff1a;BigDec…

ElementPlus设置中文

介绍 在Vue3项目将ElementPlus切换为中文 示例 第一步&#xff1a;引入中文文件 import zhCn from element-plus/dist/locale/zh-cn.mjs第二步&#xff1a;设置中文 app.use(ElementPlus,{locale: zhCn, })完整代码 // main.ts import { createApp } from vue import Ele…

mysql+关掉密码过期

mysql关掉密码过期 要在MySQL中关闭密码过期功能&#xff0c;可以按照以下步骤进行操作&#xff1a; 登录到MySQL服务器。 使用管理员账户&#xff08;如root&#xff09;连接到数据库。 mysql -uroot -ppassword 运行以下命令来查看当前的密码过期设置&#xff1a; SHOW…

Verdi常用参数说明

Verdi是一个用于数字信号处理的仿真和调试工具。在Verdi中&#xff0c;可以使用各种参数来配置仿真和调试行为。以下是一些常用的Verdi参数及其说明&#xff1a; 参数作用-f文件列表-ssf指定fsdb的路径-l设置仿真日志的输出级别&#xff0c;如"none"、“errors”、“…

金蝶EAS pdfviewlocal.jsp接口存在任意文件读取漏洞 附POC软件

免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 金蝶EAS简介 微信公众号搜索:南风漏洞复现文库 该…

2023十大最具商业影响力量子公司 | 光子盒年度系列

量子技术以其广泛的应用范围和对多个领域的深远影响&#xff0c;是当之无愧的“通用底座”技术&#xff0c;其潜在的产业变革力正在展现&#xff0c;尽管当前量子技术与人工智能或虚拟现实等技术领域相比&#xff0c;量子对大多数人来说还有些“看不透”。 2023年&#xff0c;量…

【Mars3d】new mars3d.layer.GeoJsonLayer({不规则polygon加载label不在正中间的解决方案

问题&#xff1a; 1.new mars3d.layer.GeoJsonLayer({type: "polygon",在styleOptions里配置label的时候&#xff0c;发现这个 不规则polygon加载的时候&#xff0c;会出现label不在中心位置。 graphicLayer new mars3d.layer.GeoJsonLayer({ name: "全国省界…

JVM的FastThrow优化机制

前言&#xff1a; 前一阵子&#xff0c;在公司排查线上问题发现&#xff1a;出问题的方法报空指针异常&#xff0c;但是没有异常堆栈信息和Message。我一开始以为是代码中做了处理&#xff0c;但是经过翻阅代码发现不是。最后一番查找资料&#xff0c;这种现象是JVM的一种优化机…

实验四:静态路由配置

实验四&#xff1a;静态路由配置 1. 静态路由 ( 一般配置 ) 【实验名称】静态路由配置 【实验目的】掌握静态路由的配置方法&#xff0c;理解路由表的作用和原理 【实验设备】路由器&#xff08; 2 台&#xff09;、计算机&#xff08; 2 台&#xff09;、交叉线&#xf…

Open3D 点云下采样抽稀(7)

Open3D 点云下采样抽稀&#xff08;7&#xff09; 一、算法介绍二、算法实现1.代码 一、算法介绍 点云抽稀在计算机图形学和计算机视觉中有着广泛的应用&#xff0c;其作用包括但不限于以下几点&#xff1a; 数据压缩&#xff1a; 点云抽稀可以有效地减少点云数据量&#xff0…

鸿蒙开发解决hvigor ERROR: Failed :entry:default@ProcessLibs...

文章目录 项目场景:问题描述原因分析:建议的解决方案总结HarmonyOSArkTS项目场景: 项目无法在真机上运行。报错 hvigor ERROR: Failed :entry:default@ProcessLibs… hvigor ERROR: 2 file found in ‘lib/arm64-v8a/libagccrypto.so’. This may cause unexpected errors …

问答领域的基本了解

问答领域是人工智能领域中的一个重要研究方向&#xff0c;旨在让计算机能够理解人类提出的问题&#xff0c;并以自然语言形式回答这些问题。问答系统可以应用于各种场景&#xff0c;包括搜索引擎、虚拟助手、智能客服等。 一.目标 目标&#xff1a; 问答系统的主要目标是使计…

为何大厂急招鸿蒙开发工程师?别有洞天

正确看待鸿蒙不再兼容安卓版本&#xff0c;而大厂急招鸿蒙工程师这一举动已经是预料之中的。我们一步步来看鸿蒙是怎么发展过程的。为什么互联网大厂急招鸿蒙开发岗位&#xff1f; 鸿蒙的发展历程 华为历经4年&#xff0c;从2019年开始的鸿蒙问世2.0版本到2023年末4.0宣布“不…

r语言拟合曲线

r语言拟合曲线 #圆滑曲线 library(ggalt) library(ggplot2) df <- read.csv("lqs-1.csv",headerT) p2<-ggplot(datadf,aes(xx,yy))geom_point(size1) geom_smooth(span0.1)p2结果

CTFshow web入门web128-php特性31

开启环境: 一个新的姿势&#xff0c;当php扩展目录下有php_gettext.dll时&#xff1a; _()是一个函数。 _()gettext() 是gettext()的拓展函数&#xff0c;开启text扩展get_defined_vars — 返回由所有已定义变量所组成的数组。 call_user_func — 把第一个参数作为回调函数调…

【算法练习】leetcode算法题合集之二叉树篇

递归遍历基础篇 前序遍历&#xff0c;中序遍历&#xff0c;后序遍历是根据处理根节点的位置来命名的。 树的处理大多用到了递归&#xff0c;递归需要知道终止条件。 前序遍历&#xff08;中左右&#xff09; 144.二叉树的前序遍历 中左右&#xff0c;先处理根节点&#xff0c;…

OpenGL 绘制一个三角形

在上一篇 OpenGL 顶点着色器和片段着色器的介绍实现中&#xff0c;我们向进一步绘制三角形&#xff0c;事实上只需要修改 一下两处即可 修改顶点着色器 // 顶点着色器const char* vertexShaderSource R"( #version 460 corevoid main(){// 顶点坐标vec4 vertices[3] v…

Java面试高招:程序员如何在面试中脱颖而出

Java面试高招&#xff1a;程序员如何在面试中脱颖而出 《Java面试高招&#xff1a;程序员如何在面试中脱颖而出》摘要引言面试经历面试失败的反思 面试技巧侦探式的问题解决无敌铁金刚的坚定决心 参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1…

4.5 A TILED MATRIX MULTIPLICATION KERNEL

我们现在准备展示一个tiled矩阵乘法内核&#xff0c;该内核使用共享内存来减少对全局内存的流量。图中4.16显示的内核。实施图4.15.中所示的阶段。在图4.16中&#xff0c;第1行和第2行声明Mds和Nds为共享内存变量。回想一下&#xff0c;共享内存变量的范围是一个块。因此&#…

Redis原理篇(Dict的收缩扩容机制和渐进式rehash)

Dict&#xff08;即字典&#xff09; Redis是一种键值型数据库&#xff0c;其中键与值的映射关系就是Dict实现的。 Dict通过三部分组成&#xff1a;哈希表&#xff08;DictHashTable&#xff09;&#xff0c;哈希节点(DictEntry)&#xff0c;字典&#xff08;Dict&#xff09…