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驱动工程师,都能瞄一 ...
随机推荐
- chrome 显示图片遇到的问题,与 淘宝图片服务器 缓存 有关系
最近发现使用淘宝的jae环境,一个 abc.jsp 地址,随机跳转到淘宝图片空间里任意的一张图片. 但在chrome浏览器发现一个奇怪的问题: 用户第一次访问 abc.jsp -> 302 f ...
- react与umi
我们知道umi 是一个编译工具,但它同时也是一个前端框架.它对社区的 webpack,react-router 等进行的封装, 使得我们可以基于它快速搭建一个 React 项目. 第一步:安装umi ...
- git 子模块
为了方便各个子模块独立开发,或使用第三方不断更新的仓库,可以使用子模块来引用. 子模块对应的源码是子模块仓库的克隆. git submodule 与 subtree对比 git submodule 允 ...
- Druid 配置及内置监控,Web页面查看监控内容
1.配置Druid的内置监控 首先在Maven项目的pom.xml中引入包 <dependency> <groupId>com.alibaba</groupId> ...
- (erase) Mispelling4 hdu1984
Mispelling4 Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- C++ 栈和队列的使用
要使用标准库的栈和队列,首先得添加头文件 #include <stack> #include<queue> 定义栈: stack<int> curStack; 定 ...
- 【已解决】Microsoft visual c++ 14.0 is required问题解决办法
装 识别图形验证码库tesserocr的时候,出现了Microsoft visual c++ 14.0 is required的问题,用离线安装还是没有用. 就只能乖乖装Microsoft visua ...
- GO语言的进阶之路-Golang字符串处理以及文件操作
GO语言的进阶之路-Golang字符串处理以及文件操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们都知道Golang是一门强类型的语言,相比Python在处理一些并发问题也 ...
- Linux实战型企业运维工程师试题测评
Linux实战型企业运维工程师试题答案 作者:尹正杰 最近在网上看到了一套有意思的面试题,我们一起来看一下这些题怎么破吧,哈哈~我先放在这里,有时间了一起来看看.多学点东西终究是没有坏处的! ...
- 整理备忘一波liunx命令(持续更新)
# 分区挂载 查看当前目录下的文件大小 du --max-depth= -h # 文件操作 # 编辑操作 #liunx 字体设置 苹果方字体下载安装 # 网洛端口 netstat命令各个参数说明如下: ...