- 论坛徽章:
- 0
|
linux设备模型深探(2)
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
在前面一篇
linux设备模型深探(1)
我们详细了解了底层元素kset,kobject,ktype之间的关系后,本节讲解下驱动模型中另外几个概念(bus、driver、device)为后面具体分析特定驱动(platform,pci)模型打个基础。
BUS
在设备模型中,所有的device都是通过总线bus 连接,这里的bus包括通常意义的总线如usb,pci,也包括虚拟的platform总线。
[root@wangp bus]# pwd
/sys/bus
[root@wangp bus]# ls
ac97 acpi bluetooth gameport i2c ide pci pci_express pcmcia platform pnp scsi serio usb
[root@wangp platform]# pwd
/sys/bus/platform
[root@wangp platform]# ls
devices drivers
struct bus_type {
const char * name;
struct module * owner;
struct kset subsys;
struct kset drivers;
struct kset devices;
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
struct driver_attribute * drv_attrs;
int (*match)(struct device * dev, struct device_driver * drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device * dev);
int (*remove)(struct device * dev);
void (*shutdown)(struct device * dev);
int (*suspend)(struct device * dev, pm_message_t state);
int (*suspend_late)(struct device * dev, pm_message_t state);
int (*resume_early)(struct device * dev);
int (*resume)(struct device * dev);
unsigned int drivers_autoprobe:1;
};
name是总线的名字,每个总线下都有自己的子系统,其中包含2个kset,deviece和driver,分别代表已知总线的驱动和插入总线的设备
如platform总线的声明如下:
struct bus_type platform_bus_type = {
.name = "platform",
.dev_attrs = platform_dev_attrs,
.match = platform_match,
.uevent = platform_uevent,
.suspend = platform_suspend,
.suspend_late = platform_suspend_late,
.resume_early = platform_resume_early,
.resume = platform_resume,
};
只有很少的bus_type成员需要初始化,大部分交给kernel来处理
关于总线的操作常用的如下:
int bus_register(struct bus_type * bus);
void bus_unregister(struct bus_type * bus);
/* iterator helpers for buses */
列举总线上从start之后的每个设备,并进行fn操作,通常用途是对bus上的设备和驱动进行绑定
int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *));
int driver_attach(struct device_driver * drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}
static int __driver_attach(struct device * dev, void * data)
{
struct device_driver * drv = data;
/*
* Lock device and try to bind to it. We drop the error
* here and always return 0, because we need to keep trying
* to bind to devices and some drivers will return an error
* simply if it didn't support the device.
*
* driver_probe_device() will spit a warning if there
* is an error.
*/
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}
几乎linux设备模型的每一层都提供了添加属性的函数,总线也不例外
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf); //显示属性
ssize_t (*store)(struct bus_type *, const char * buf, size_t count); //设置属性
};
创建属于一个总线的属性使用(在模块的加载时间完成)
int bus_create_file(struct bus_type *,struct bus_attribute *);
void bus_remove_file(struct bus_type *, struct bus_attribute *);
在说明下bus在sysfs里面的结构,刚才已经讲过,bus_type中有2个kset结构对应于device和driver,也就是说每个bus下面都会有device何driver2个文件夹。
首先在总线上注册的驱动会得到一个文件夹driver,如platform驱动
[root@wangp platform]# pwd
/sys/bus/platform
[root@wangp platform]# ls
devices drivers
[root@wangp drivers]# pwd
/sys/bus/platform/drivers
[root@wangp drivers]# ls
i8042 pcspkr serial8250 vesafb
而任何在总线/sys/bus/xxx/上发现的设备会得到一个symlink(符号链接)即/sys/bus/xxx/device指向/sys/device/xxx下面的文件夹
[root@wangp devices]# pwd
/sys/bus/platform/devices
[root@wangp devices]# ls -l
total 0
lrwxrwxrwx 1 root root 0 Jun 6 10:37 bluetooth -> ../../../devices/platform/bluetooth
lrwxrwxrwx 1 root root 0 Jun 6 10:37 floppy.0 -> ../../../devices/platform/floppy.0
lrwxrwxrwx 1 root root 0 Jun 6 10:37 i8042 -> ../../../devices/platform/i8042
lrwxrwxrwx 1 root root 0 Jun 6 10:37 pcspkr -> ../../../devices/platform/pcspkr
lrwxrwxrwx 1 root root 0 Jun 6 10:37 serial8250 -> ../../../devices/platform/serial8250
lrwxrwxrwx 1 root root 0 Jun 6 10:37 vesafb.0 -> ../../../devices/platform/vesafb.0
<SPAN style="FONT-SIZE: 9pt; COLOR: black; FON
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/109300/showart_2146861.html |
|