教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 政务民生 >

linux设备模型深探(8)

来源:网络收集 时间:2026-08-05
导读: #define __ATTR(_name,_mode,_show,_store) { \\ .attr = {.name = __stringify(_name), .mode = _mode }, \\ .show = _show, \\ .store = _store, \\ } 由此可见.上面这三个属性对应的名称为别为uevent, drivers_p

#define __ATTR(_name,_mode,_show,_store) { \\

.attr = {.name = __stringify(_name), .mode = _mode }, \\

.show = _show, \\

.store = _store, \\ }

由此可见.上面这三个属性对应的名称为别为uevent, drivers_probe, drivers_autoprobe.也就是说,会在bus_types目录下生成三个文件,分别为uevent,probe,autoprobe.

根据之前的分析,我们知道在sysfs文件系统中,对普通属性文件的读写都会回溯到kobject->ktype->sysfs_ops中.在这里,注意到有:

priv->subsys.kobj.kset = bus_kset;

priv->subsys.kobj.ktype = &bus_ktype;

显然,读写操作就回溯到了bus_ktype中.定义如下:

static struct kobj_type bus_ktype = {

.sysfs_ops = &bus_sysfs_ops, };

static struct sysfs_ops bus_sysfs_ops = {

.show = bus_attr_show,

.store = bus_attr_store, };

Show和store函数对应的代码为:

static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr,

char *buf) {

struct bus_attribute *bus_attr = to_bus_attr(attr);

struct bus_type_private *bus_priv = to_bus(kobj);

ssize_t ret = 0;

if (bus_attr->show)

ret = bus_attr->show(bus_priv->bus, buf);

return ret; }

static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr,

const char *buf, size_t count) {

struct bus_attribute *bus_attr = to_bus_attr(attr);

struct bus_type_private *bus_priv = to_bus(kobj);

ssize_t ret = 0;

if (bus_attr->store)

ret = bus_attr->store(bus_priv->bus, buf, count);

return ret; }

从代码可以看出.读写操作又会回溯到bus_attribute中的show和store中.在自定义结构里嵌入struct attribute,.然后再操作回溯到自定义结构中,这是一种比较高明的架构设计手法.

闲言少叙.我们对应看一下上面三个文件对应的最终操作:

Uevent对应的读写操作为:NULL, bus_uevent_store.对于这个文件没有读操作,只有写操作.用cat 命令去查看这个文件的时候,可能会返回”设备不存在”的错误.bus_uevent_store()代码如下:

static ssize_t bus_uevent_store(struct bus_type *bus,

const char *buf, size_t count) {

enum kobject_action action;

if (kobject_action_type(buf, count, &action) == 0)

kobject_uevent(&bus->p->subsys.kobj, action);

return count; }

从这里可以看到,可以在用户空间控制事件的发生,如echo add > event就会产生一个add的事件,

Probe文件对应的读写操作为:NULL store_drivers_probe.

store_drivers_probe()这个函数的代码涉及到struct device.等分析完struct device可以自行回过来看下这个函数的实现.实际上,这个函数是将用户输和的设备名称对应的设备与驱动匹配一次.

Autoprobe文件对应的读写操作为show_drivers_autoprobe, store_drivers_autoprobe.对应读的代码为:

static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) {

return sprintf(buf, \

}

它将总线对应的drivers_autoprobe的值输出到用户空间,这个值为1时,自动将驱动与设备进行匹配.否则,反之.

写操作的代码如下:

static ssize_t store_drivers_autoprobe(struct bus_type *bus,

const char *buf, size_t count) {

if (buf[0] == '0')

bus->p->drivers_autoprobe = 0;

else

bus->p->drivers_autoprobe = 1;

return count; }

写操作就会改变bus->p->drivers_autoprobe的值.

就这样,通过sysfs就可以控制总线是否要进行自动匹配了.

从这里也可以看出.内核开发者的思维是何等的灵活.

我们从sysfs中找个例子来印证一下:

Cd / sys/bus/usb

用ls命令查看:

devices drivers drivers_autoprobe drivers_probe uevent

与上面分析的相吻合

设备的注册接口为: device_register().

int device_register(struct device *dev) {

device_initialize(dev);

return device_add(dev); }

Device_initialize()中有几个很重要的操作,如下:

void device_initialize(struct device *dev) {

dev->kobj.kset = devices_kset;

kobject_init(&dev->kobj, &device_ktype);

klist_init(&dev->klist_children, klist_children_get,

klist_children_put);

INIT_LIST_HEAD(&dev->dma_pools);

INIT_LIST_HEAD(&dev->node);

init_MUTEX(&dev->sem);

spin_lock_init(&dev->devres_lock);

INIT_LIST_HEAD(&dev->devres_head);

device_init_wakeup(dev, 0);

set_dev_node(dev, -1); }

在这里,它为device的内嵌kobject指定了ktype和kset.device_kset的值如下:

devices_kset = kset_create_and_add(\

…… 此处隐藏:1150字,全部文档内容请下载后查看。喜欢就下载吧 ……
linux设备模型深探(8).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/448127.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)