Linux内核平台总线设备驱动模型浅析
复习总线设备驱动模型,做了一点小笔记,大牛略过。
一、Linux系统的驱动框架的基础很大一部分是围绕着总线设备驱动模型展开的。
二、涉及3个重要结构体:
struct bus_type:总线
struct device :设备
struct device_driver:驱动
三、结构体核心代码分析(2.6.38内核)
structbus_type
{
const char *name; // 总线名
struct bus_attribute *bus_attrs; //总线属性文件,会显示在/sys/xxx中
struct device_attribute *dev_attrs; //设备属性文件
struct driver_attribute *drv_attrs; // 驱动属性文件
int (*match)(struct device*dev, struct device_driver *drv);//驱动与设备是否匹配的检测函数
struct subsys_private *p;
};
其中,struct subsys_private包含一个设备链表(struct klist klist_devices)和一个驱动链表( struct klist klist_drivers)
structdevice
{
struct kobject kobj;
const char //设备名
struct bus_type *bus; // 该设备挂接在哪条总线上
struct device_driver*driver; //该设备所对应的驱动
void *platform_data; // 平台特定数据,一般我们移植内核时需填充该结构体(如支持mini2440的nandflash,dm9000等)
dev_t devt; // 设备号
};
任何建立在平台总线设备驱动模型基础上的驱动代码(如平台驱动,PCI驱动,USB驱动,I2C驱动,SPI驱动等),它们的设备结构体(如platform_device, pci_dev,usb_device,i2c_device, spi_device等)都包含一个struct device结构体,当这些驱动向内核注册各式各样的设备时,其实最终都会调用到:
intdevice_register(struct device *dev)
{
device_initialize(dev); //做各类初始化
//将设备挂接在对应的总线上,主要工作把设备(device)添加到总线 (bus_type)的klist_devices链表
return device_add(dev);
}
structdevice_driver {
const char *name;// 驱动名
struct bus_type *bus;// 该驱动所属的总线
int (*probe) (struct device *dev);// 指向设备探测函数
int (*remove) (struct device*dev);// 指向设备移除函数
struct driver_private *p;
};
同理,任何建立在平台总线设备驱动模型基础上的驱动代码(如平台驱动,PCI驱动,USB驱动,I2C驱动,SPI驱动等),它们的驱动结构体(如platform_driver, pci_driver,usb_driver,i2c_driver,spi_driver等)都包含一个structdevice_driver结构体,当这些驱动向内核注册各式各样的驱动时,最终都会调用到:
int driver_register(structdevice_driver *drv)
{
// 将驱动绑定在对应的总线上,主要工作把驱动(device_driver)添加到总线(bus_type)的klist_drivers链表中去
ret =bus_add_driver(drv);
}
无论是调用driver_register()注册驱动, 还是用device_register注册设备, 内核都会调用总线的match函数来探测是否有合适device_driver的device或者是否有合适device的device_driver,如果match成功,则会调用device_driver的probe函数进行更进一步的探测。
这样我们就可以站在一个新的高度上看驱动了
更具体的内容比如怎么探测设置probe请看韦东山2期驱动大全相关视频。
- python类中super()和__init__()的区别
- Python正则表达式:最短匹配
- 转--Go时间格式化和类型互换操作
- Python标准库(1) — itertools模块
- Linux笔记:使用Vim编辑器
- 一步一步学lucene——(第二步:示例篇)
- 类属性的延迟计算
- 一步一步学lucene——(第三步:索引篇)
- 在Python应用中使用MongoDB
- Python检查xpath和csspath表达式是否合法
- 一步一步学lucene——(第四步:搜索篇)
- Python爬虫代理IP池
- SSDB图形界面管理工具:phpssdbadmin安装部署
- [Go 语言社区] 初始化内存数据--游戏列表数据
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- mysql各种引擎对比、实战
- 接球小游戏玩腻了?换个姿势让PaddleX帮你吊打游戏系统
- mysql事务隔离级别详解和实战
- ELK+FileBeat+Kafka分布式系统搭建图文教程
- Flink CEP 原理和案例详解
- 实战开发,使用 Spring Session 与 Spring security 完成网站登录改造!!
- 分布式计算框架Gearman原理详解
- 【从0开始の全记录】Flume+Kafka+Spark+Spring Boot 统计网页访问量项目
- 系统级性能分析工具perf的介绍与使用[转]
- 深入理解排序算法
- 用nginx缓存静态文件
- 优雅的玩PHP多进程
- 聊一聊mycat数据库集群系列之双主双重实现
- Fast-SCNN的解释以及使用Tensorflow 2.0的实现
- 基于Spring Boot快速实现发送邮件功能