linux设备模型:扩展篇
Linux设备模型组件:总线
一、定义:
总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至当它是一个内部的虚拟总线(如,platform总线);例如,设备模型表示在总线和它们控制的设备之间的实际连接;
常见的总线有:PCI、ISA、EISA、VESA、USB、IIC、IIS、SPI、SCI、CAN、RS-232-C、RS-485、IEEE-488,等等;
Linux设备模型中,一个总线由内核结构体struct bus_type描述;其结构定义如下:
struct bus_type
{
const char* name; //总线类型的名称
struct subsystem subsys; //该总线所属的子系统subsystem,代表自身---kset
struct kset drivers; //该总线所使用的驱动程序的集合
struct kset devices; //挂接在该总线上的所有设备的集合
struct klist klist_devices; //挂接在该总线上的所有设备所组成的链表
struct klist klist_drivers; //该总线所使用的驱动程序所组成的链表
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, char** envp, int num_envp, char* buffer, int buffer_size);
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 (*resume)(struct device* dev);
};
每个bus_type对象都对应/sys/bus目录下的一个子目录,如,PCI总线对应于/sys/bus/pci目录;在每个这样的子目录下存在两个子目录:devices和drivers,分别对应于bus_type结构中的devices和drivers成员,其中,devices子目录描述的是连接在该总线上的所有设备,drivers子目录描述的是该总线所使用的所有驱动程序;/sys/bus目录下的所有子目录都类似;
二、相关函数:
1、int bus_register(struct bus_type* bus); //注册函数
2、void bus_unregister(struct bus_type* bus); //注销函数
3、void bus_rescan_devices(struct bus_type* bus); //扫描函数
4、int bus_for_each_dev(struct bus_type* bus, struct device* start, void* data, int (*fn)(struct device*, void*));
//该函数用于遍历指定总线上的已知设备;
5、int bus_for_each_drv(struct bus_type* bus, struct device_driver* start, void* data, int (*fn)(struct device_driver*, void*));
//该函数用于遍历指定总线上已知的驱动程序;
6、struct device* bus_find_device(struct bus_type* bus, struct device* start, void* data, int (*match)(struct device*, void*));
//该函数用于在指定总线上查找指定设备,并返回该设备的指针;
三、总线属性:
Linux设备模型中,几乎每一层都提供一个添加属性的接口,总线层也不例外;
总线层的属性类型定义如下:
struct bus_attribute
{
struct attribute attr;
ssize_t (*show)(struct bus_type* bus, char* buf);
ssize_t (*store)(struct bus_type* bus, const char* buf, size_t count);
};
int bus_create_file(struct bus_type* bus, struct bus_attribute* attr):为指定总线添加属性;
void bus_remove_file(struct bus_type* bus, struct bus_attribute* attr):删除指定总线上的指定属性;
备注:struct bus_type、struct bus_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;
Linux设备模型组件:设备
一、定义:
Linux设备模型中,在系统的最底层,每一个设备都由一个struct device对象来描述;struct device结构用于描述设备自身的信息、与其它设备之间的关系、与总线和驱动之间的关系;其定义如下:
struct device
{
struct klist klist_children; //设备列表中的子列表
struct klist_node knode_parent; //兄弟节点
struct klist_node knode_driver; //驱动程序节点
struct klist_node knode_bus; //总线节点
struct device* parent; //父设备节点,即,当前设备所附着到的设备
struct kobject kobj; //代表当前设备,并连接它到层次中的kobject
char bus_id[BUS_ID_SIZE]; //唯一确定这个总线上的设备的字符串,即,总线上设备的位置
struct device_attribute uevent_attr;
struct device_attribute* devt_attr;
struct semaphore sem; //信号量
struct bus_type* bus; //总线类型,即,哪种总线
struct device_driver* driver; //这个设备所使用的驱动程序
void* driver_data; //一个可能被设备驱动程序所使用的私有数据
void* platform_data; /* Platform specific data, device core doesn't touch it */
void* firmware_data; /* Firmware specific data (e.g. ACPI, BIOS data),reserved for device core*/
struct dev_pm_info power;
u64* dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;
struct list_head dma_pools; /* dma pools (if dma'ble) */
struct dma_coherent_mem* dma_mem; /* internal for coherent mem override */
struct list_head node; /* class_device migration path */
struct class* class; /* optional */
dev_t devt; /* dev_t, creates the sysfs "dev" */
void (*release)(struct device* dev); //释放设备的函数
};
二、相关函数:
int device_register(struct device* dev):设备注册;
void device_unregister(struct device* dev):设备注销;
void device_initialize(struct device* dev):设备初始化;
int device_add(struct device* dev):添加设备到设备模型的层次结构中;
void device_del(struct device* dev):设备模型的层次结构中删除设备;
int device_for_each_child(struct device*, void*, int (*fn)(struct device*, void*)):遍历设备的子列表;
void device_bind_driver(struct device* dev):给设备绑定一个驱动程序;
void device_release_driver(struct device* dev):去掉设备上的驱动程序,即,删除设备与驱动程序之间的绑定关系;
struct device* device_create(struct class* cls, struct device* parent, dev_t devt, char* fmt, ...):创建一个设备;
void device_destroy(struct class* cls, dev_t devt):销毁一个设备;
struct device* get_device(struct device* dev):增加设备的引用计数;
void put_device(struct device* dev):减少设备的引用计数;
三、设备属性:
struct device_attribute
{
struct attribute attr;
ssize_t (*show)(struct device* dev, struct device_attribute* attr, char* buf);
ssize_t (*store)(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);
};
int device_create_file(struct device* dev, struct device_attribute* attr):为指定设备添加属性;
void device_remove_file(struct device* dev, struct device_attribute* attr):删除指定设备上的指定属性;
备注:struct device、struct device_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;
Linux设备模型组件:驱动
一、定义:
系统中的每一个硬件设备都由一个驱动程序来管理;内核中使用struct device_driver结构对象来描述一个设备的驱动程序;定义如下:
struct device_driver
{
const char* name; //设备驱动程序的名字
struct bus_type* bus; //所属的总线
struct completion unloaded;
struct kobject kobj; //内嵌的kobject对象,代表自身
struct klist klist_devices; //使用该驱动程序的设备列表,即,该驱动程序所管理的所有设备
struct klist_node knode_bus;
struct module* owner; //所属模块
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 (*resume)(struct device* dev);
};
二、相关函数:
int driver_register(struct device_driver* drv):驱动程序注册;
void driver_unregister(struct device_driver* drv):驱动程序注销;
struct device_driver* get_driver(struct device_driver* drv):增加驱动程序引用计数;
void put_driver(struct device_driver* drv):减少驱动程序引用计数;
struct device_driver* driver_find(const char* name, struct bus_type* bus):在指定总线上查找指定名字的驱动程序;
三、驱动程序属性:
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);
};
int driver_create_file(struct device_driver* drv, struct driver_attribute* attr); //为指定驱动程序添加属性;
void driver_remove_file(struct device_driver* drv, struct driver_attribute* attr); //删除指定驱动程序上的指定属性;
int driver_for_each_device(struct device_driver* drv, struct device* start, void* data, int (*fn)(struct device*, void*));
//遍历驱动程序所管理的所有设备;
struct device* driver_find_device(struct device_driver* drv, struct device* start, void* data, int (*match)(struct device*, void*));
//查找驱动程序所使用的设备;
备注:struct device_driver、struct driver_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中。
Linux设备模型组件:设备类
一、定义:
系统中的设备所属的类有结构体struct class对象来描述,用于表示某一类设备,它是一组具有共同属性和功能的设备的抽象体,类似于面向对象中的类的概念;所有的class对象都属于class_subsys子系统,对应于/sys/class目录;
其结构定义如下:
struct class
{
const char* name; //类名
struct module* owner; //所属模块
struct subsystem subsys; //所属子系统subsystem
struct list_head children; //属于该class类型的所有子类组成的链表;
struct list_head devices; //属于该class类型的所有设备class_device组成的链表;
struct list_head interfaces; //类接口class_interface链表
struct semaphore sem; /* locks both the children and interfaces lists */
struct class_attribute* class_attrs; //类属性
struct class_device_attribute* class_dev_attrs; //类设备属性
int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
void (*release)(struct class_device* dev);
void (*class_release)(struct class* class);
};
int class_register(struct class *cls); //类注册;
void class_unregister(struct class *cls); //类注销;
二、设备类属性:
struct class_attribute
{
struct attribute attr;
ssize_t (*show)(struct class* cls, char* buf);
ssize_t (*store)(struct class*, const char* buf, size_t count);
};
int class_create_file(struct class* cls, const struct class_attribute* attr); //为指定设备类增加指定属性;
void class_remove_file(struct class* cls, const struct class_attribute* attr); //删除指定设备类上的指定属性;
备注:struct class、struct class_attribute结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中;
Linux设备模型组件:类设备
一、定义:
一个设备类struct class的真正目的是作为一个该类具体实例(设备)的容器使用;一个设备类的具体实例由struct class_device结构来描述;也可以这样理解:struct class类型相当于面向对象系统中的类的概念,而struct class_device类型相当于面向对象系统中的实例对象的概念;只有在应用具体实例对象的时候,它的类才有意义;
类设备struct class_device结构定义如下:
struct class_device
{
struct list_head node;
struct kobject kobj; //内嵌的kobject对象
struct class* class; //所属的设备类class
dev_t devt; //设备编号
struct class_device_attribute* devt_attr; //类设备属性
struct class_device_attribute uevent_attr; //类设备事件属性
struct device* dev; //如果存在,则创建到/sys/devices目录下相应入口的符号链接
void* class_data; //类私有数据
struct class_device* parent; //父设备,即,当前设备所附着到的设备
struct attribute_group** groups; /* optional groups */
void (*release)(struct class_device* dev);
int (*uevent)(struct class_device* dev, char** envp, int num_envp, char* buffer, int buffer_size);
char class_id[BUS_ID_SIZE]; //类唯一标识
};
二、类设备相关函数
int class_device_register(struct class_device* cd); //类设备注册;
void class_device_unregister(struct class_device* cd); //类设备注销;
int class_device_rename(struct class_device* cd, char* new_name); //类设备重命名;
void class_device_initialize(struct class_device* cd); //类设备初始化;
int class_device_add(struct class_device* cd); //把类设备对象加入到设备模型的层次结构中;
void class_device_del(struct class_device* cd); //把类设备对象从设备模型的层次结构中删除;
struct class_device * class_device_get(struct class_device* cd); //给类设备对象增加引用计数;
void class_device_put(struct class_device* cd); //给类设备对象减少引用计数;
备注:每一个设备类class对象都包含一个类设备class_device对象的链表,而每一个类设备class_device对象又表示一个逻辑设备,并通过类设备struct class_device结构中的dev成员(一个指向struce device的指针)关联到一个物理设备上;这样,一个逻辑设备总是对应于一个物理设备;但是,一个物理设备却可能对应多个逻辑设备。
三、类设备属性:
struct class_device_attribute
{
struct attribute attr;
ssize_t (*show)(struct class_device* cls, char* buf);
ssize_t (*store)(struct class_device* cls, const char* buf, size_t count);
};
int class_device_create_file(struct class_device* cd, const struct class_device_attribute* attr); //为指定类设备增加指定属性;
void class_device_remove_file(struct class_device* cd, const struct class_device_attribute* attr); //删除指定类设备上的指定属性;
int class_device_create_bin_file(struct class_device* cd, struct bin_attribute* attr);
void class_device_remove_bin_file(struct class_device* cd, struct bin_attribute* attr);
四、类接口:
当设备加入或离开类时,将引发class_interface中的成员函数被调用;
struct class_interface
{
struct list_head node;
struct class* class; //对应的设备类class
int (*add)(struct class_device* cd, struct class_interface* ci); //设备加入时触发
void (*remove)(struct class_device* cd, struct class_interface* ci); //设备移除时触发
};
int class_interface_register(struct class_interface* ci); //类接口注册;
void class_interface_unregister(struct class_interface* ci); //类接口注销;
struct class* class_create(struct module* owner, char* name); //创建类;
void class_destroy(struct class* cls); //销毁类;
struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, struct device *device, char *fmt, ...); //创建类设备
void class_device_destroy(struct class *cls, dev_t devt);//销毁类设备
备注:struct class_device、struct class_device_attribute、struct class_interface结构均定义在/usr/src/kernels/2.6.18-8.el5-i686/include/linux/device.h文件中。
示例代码下载链接:http://download.csdn.net/detail/klcf0220/5865769
Input子系统分析 下载链接:http://download.csdn.net/detail/klcf0220/5874587
linux设备模型:扩展篇的更多相关文章
- Linux 设备模型浅析之 uevent 篇(2)
Linux 设备模型浅析之 uevent 篇 本文属本人原创,欢迎转载,转载请注明出处.由于个人的见识和能力有限,不可能面 面俱到,也可能存在谬误,敬请网友指出,本人的邮箱是 yzq.seen@gma ...
- Linux设备模型:基础篇
linux提供了新的设备模型:总线(bus).设备(device).驱动(driver).其中总线是处理器与设备之间通道,在设备模型中,所有的设备都通过总线相连:设备是对于一个设备的详细信息描述,驱动 ...
- Linux设备模型——设备驱动模型和sysfs文件系统解读
本文将对Linux系统中的sysfs进行简单的分析,要分析sysfs就必须分析内核的driver-model(驱动模型),两者是紧密联系的.在分析过程中,本文将以platform总线和spi主控制器的 ...
- Linux 设备模型之 (kobject、kset 和 Subsystem)(二)
问题描写叙述:前文我们知道了/sys是包括内核和驱动的实施信息的,用户能够通过 /sys 这个接口.用户通过这个接口能够一览内核设备的全貌.本文将从Linux内核的角度来看一看这个设备模型是怎样构建的 ...
- Linux设备模型(热插拔、mdev 与 firmware)【转】
转自:http://www.cnblogs.com/hnrainll/archive/2011/06/10/2077469.html 转自:http://blog.chinaunix.net/spac ...
- linux设备模型与内核中的面向对象思想
linux内核用C语言实现了C++面向对象的大部分特性:封装,继承,多态.在看内核的过程中,开始追寻其中的设计思想,封装.继承.多态.恰好今天又在看Linux设备模型,找了很多资料.总结如下: 1.l ...
- Linux设备模型之kobject
阿辉原创,转载请注明出处 参考文档:LDD3-ch14.内核文档Documentation/kobject.txt,本文中使用到的代码均摘自Linux-3.4.75 ----------------- ...
- linux设备模型_转
建议原博文查看,效果更佳. 转自:http://www.cnblogs.com/wwang/category/269350.html Linux设备模型 (1) 随着计算机的周边外设越来越丰富,设备管 ...
- Linux设备模型(9)_device resource management ---devm申请空间【转】
转自:http://www.wowotech.net/linux_kenrel/device_resource_management.html . 前言 蜗蜗建议,每一个Linux驱动工程师,都能瞄一 ...
随机推荐
- 洛谷P2668 斗地主
好,终于搞完了这一道毒瘤题...... 先想到搜索,然后想到状压,发现数据组数很多,又是随机,还是决定用搜索. 先搜出的多的,于是顺序是三个顺子,然后按照多到少搜带牌,最后是不带牌. 大体思路很简单, ...
- A1053. Path of Equal Weight
Given a non-empty tree with root R, and with weight Wi assigned to each tree node Ti. The weight of ...
- 收藏:SQL重复记录查询 .
来自:http://blog.csdn.net/chinmo/article/details/2184020 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断select ...
- ref实现输入框聚焦
关于ref我们是怎么理解的呢? 我们可以通过React.createRef()创建一个 ref节点,并将其打印出来. 代码如下: import React,{Component} from 'reac ...
- CentOS6.7下Ansible部署
Ansible是一种集成IT系统的配置管理, 应用部署, 执行特定任务的开源平台. 它基于Python语言实现, 部署只需在主控端部署Ansible环境, 被控端无需安装代理工具, 只需打开SSH, ...
- SQL Server 窗口函数详解:OVER()
语法 开窗函数支持分区.排序和框架三种元素,其语法格式如下: OVER ( [ <PARTITION BY clause> ] [ <ORDER BY clause> ] [ ...
- 51job_selenium测试
Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...
- Elasticsearch日志分析系统
Elasticsearch日志分析系统 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是Elasticsearch 一个采用Restful API标准的高扩展性的和高可用性 ...
- Linux Shell 笔记
1.查看进程的环境变量 普通:$cat /proc/1642/environ 换行:$cat /proc/1642/environ | tr '\0' '\n' tr的命令格式是tr SET1 SE ...
- Linux下网卡绑定模式
Linux bonding驱动一共提供了7种模式,它们分别是:balance-rr .active-backup.balance-xor.broadcast.802.3ad.balance-tlb.b ...