linux 设备模型

来源:互联网 发布:云南边境贩毒知乎 编辑:程序博客网 时间:2024/06/06 20:51

2.6内核的设备模型支持以下特性:

1. 电源管理

2. 与用户空间通信

3. 热插拔设备

4. 设备类型管理

5. 对象生命周期

 

§1. 底层组件kobject, kset, kobj_type, ksubsystem(merge to kset after 2.6.31)

kobject对象有名字和引用计数。每个kobject对应一个kobj_type(由kobject结构自己提供,或者kobject所属的kset指定)。

kset对应kobject的聚合,每个kset都在sysfs中以目录的形式出现;kobject不必在sysfs虚拟文件系统中出现,但kset中的kobject成员都在sysfs中出现。kset在内核链表中保存了它的子节点。

|---------------Kset(内部有自己的kobject)-------------|

|                                                                                                                                                          |

|--------list node-----list node 。。。。。。。--list node-------- |  // 每个list node指向一个kobject对象

 

§2. bus, device and driver

bus的结构为bus_type,在内核中所有的bus都在bus_kset链表上,注册函数为bus_register(此函数中也会创建并初始化bus的两个成员:devices_kset,drivers_kset,并且调用bus_create_file在bus目录下创建属性文件)。bus_type的主要成员有name,match,probe,hotplug,uevent,remove,resume,suspend等。

device为系统的各个设备(注意:不是一类)。如PCI总线,在pci_legacy_init或pci_numaq_init的时候就遍历各总线,形成pci_bus或pci_dev的树,同时将各个device添加到pci_bus_type的klist_devices。pci_bus可以有多个,但是pci_bus_type只有一个。每个pci设备对应一个devicename为[domain:bus:slot:fn]各不相同。在此后调用driver_register的时候,会依次遍历bus->klist_devices,如果匹配的话,将dev添加到driver->klist_devices

driver的结构为device_driver,主要成员包括name,*bus_type,probe,match,shutdown,remove,supend,resume,*dev_pm_ops,*klist_devices,knode_bus(链接到bus上)等。driver_register依次查找各bus_type的klist_devices,如果匹配的话将设备添加到driver->klist_devices。

 注:

一般而言,只要是采用PCI总线的机器,BIOS提供对PCI总线操作的支持,因而称为PCI BIOS。最早Linux内核也是通过这种BIOS调用的方式来获取系统中的PCI设备信息的;但有的平台没有BIOS(如某些嵌入式系统),或者有些PCI BIOS存在问题,所以后来Linux内核自己动手了。Linux内核在make menuconfig选项PCI access mode里面提供BIOS、MMconfig、Direct和Any,其中Direct就是抛开BIOS由内核自己完成初始化。 

 §3.字符设备(块设备一般用于磁盘等,不做研究)

 下图为字符设备的组织图:

点击查看原始尺寸

 

字符设备:字符设备的内核结构为cdev:

struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
这里面一个重要的成员是kobj,在cdev_add的时候添加到系统中;ops用于对字符设备的操作。

字符设备模型目的是对用户暴露出/dev下的设备,用户可以把设备当作文件进行open,read,write等操作。 在open系统调用中,内核将inode->i_cdev设置为cdev对象,然后在用户注册的fops->open中可以将此cdev(或包含cdev的用户自定义结构)赋值给filp->private_data,这样以后的文件操作都可以对cdev操作。

cdev_add 函数将cdev结构添加进系统中的cdev_map[255]数组。

2.6以后的platform_device 专门用于对无总线的设备的处理(最初用于统一管理嵌入式系统上的设备)。相对于cdev来说,电源管理、sysfs节点都可以配套实现;但因为platform无自动探测功能,需要用户手工添加设备(这跟cdev一样)。

§4 sysfs 文件系统,用于描述内核空间的设备。bus,driver,device在这里都有对应的目录。在未知一个设备用哪一个驱动的情况下可以先从/sys/module/ 查找相应模块的情况,再从 drivers找对应的驱动程序;或者反过来利用这些信息,先用找到/sys/devices/下的设备节点,再从其设备的driver 链接找到/sys/bus/*/drivers/下的device_driver, 再从device_driver下的module链接找到/sys/module/*/,这样就知道是哪一个模块给设备提供驱动程序。

原创粉丝点击