专栏首页韦东山嵌入式Linux内核平台总线设备驱动模型浅析

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期驱动大全相关视频。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 新人怎样学习嵌入式Linux?

    作为一个新人,怎样学习嵌入式Linux?被问过太多次,特写这篇文章来回答一下。 在学习嵌入式Linux之前,肯定要有C语言基础。汇编基础有没有无所谓(就那么几条...

    韦东山
  • 第018课 ADC和触摸屏硬件原理详解及裸机编程

    模数转换器即A/D转换器,或简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件。 通常的模数转换器是把经过与标准量比较处理后的模拟量转换成以二进制数值...

    韦东山
  • jz2440重新分区

    在购买开发板的时候,板子上已经烧写好了bootloader、内核和文件系统。但是在具体使用时,发现板子上划分的内核分区只有2M,但是我编译出来的内核大于2M,于...

    韦东山
  • CSRF原理和防范

    一.CSRF CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/sessi...

    苦咖啡
  • 跨站请求伪造(CSRF)攻击

    跨站请求伪造(CSRF)攻击强迫终端用户在他们身份被认证的情况下执行对于目标应用未知的操作(恶意的)。CSRF 攻击一般针对状态更改请求,而不是数据被盗,因为攻...

    madneal
  • CSRF攻击那点事

    1.基本知识概述CSRF英文全称(Cross-Site Request Forgery)常常被称为“One Click

    字节脉搏实验室
  • MySQL 的四种 GROUP BY 用法

    在我的上一篇文章中,我们知道了通过索引或者其他的方式获取数据可能不是语句执行最耗时的操作。比如,MySQL 的GROUP BY可能会占据语句执行时间的90%.

    wubx
  • MySQL的四种GROUP BY用法

    在我的上一篇文章中,我们知道了通过索引或者其他的方式获取数据可能不是语句执行最耗时的操作。比如,MySQL 的GROUP BY可能会占据语句执行时间的90%.

    wubx
  • ReactiveSwift源码解析(四) Signal中的静态属性静态方法以及面向协议扩展

    上篇博客我们聊了Signal的几种状态、Signal与Observer的关联方式以及Signal是如何向关联的Observer发送事件的。本篇博客继续上篇博客的...

    lizelu
  • 跨站请求伪造(CSRF)挖掘技巧及实战案例全汇总

    Cross-Site Request Forgery跨站请求伪造漏洞,简称CSRF或XSRF,强制最终用户在当前对其进行身份验证的Web应用程序上执行不需要的操...

    Jayway

扫码关注云+社区

领取腾讯云代金券