zoukankan      html  css  js  c++  java
  • 关于driver_register做了些什么

    现在进入driver_register()函数去看看。在driver_register() 中,调用了driver_find(drv->name, drv->bus)函数,这里是干啥呢?这里是先去驱动打算挂牌的地方先查找一下,这个驱动是否已经挂牌(注册)过了。在哪里查找呢?代码中写得很清楚,去bus->p->drivers_kset中查找,看到这里,我决定这里不要再继续展开细细的分析,否则永远都无法把内核看明白,有时候必须对细节很了解,有时候只要明白他的工作原理就可以,不必太细碎。简单的看,drivers_kset就是一个klist链表,链表的节点都是内核对象,也就是kobject。kset中的kobject可以是不同“类型”的(different “type”),kset只是把一类需要用进行相同处理的kobject放在一起。driver_find函数其实也不干活,它是调用kset_find_obj函数去遍历链表根据drv->name去寻找,我不管找的过程,反正如果找到了driver_find()就返回指向已经注册的驱动的指针,如果没找到就返回NULL。
    回到driver_register() ,如果驱动已经注册过了,那就退出好了。如果没有注册,接下来调用bus_add_driver(struct device_driver *drv) 函数注册驱动。这个函数有点长,主要作用就是把drv放到drv->bus->p->klist_drivers链表的尾部。到此就完成注册工作。
    阅读了一些老手的笔记,看了一点内核代码,看了LDD,再加上自己的猜测,现在对驱动的工作机制有了一点认识。
    内核在维护两条链表,一个用来记录devices,一个用来记录drivers。系统接电开机后,总线就扫一遍有哪些设备接到计算机上了,每个设备都对应一个设备对象,然后就把设备对象填入到记录devices的链表中。接着系统继续启动,到了加载驱动的过程,把驱动对象都填入到记录drivers的链表中。每加载一个驱动,就去遍历一次devices链表,看看有没有自己要服务的设备,如果有,就把该设备对象的驱动指针指向自己,同时把该设备对象加入到驱动程序维护的设备链表中,该设备链表记录了这个驱动能够服务的设备。这是在开机之前硬件就和计算机连接好的工作方式,但是现在更实用的是另外一种工作方式,就是热插拔。
    热插拔意味着设备和驱动没有谁先谁后进入系统,因为都有可能。所以工作方式就是一旦有一个设备插入,总线把对应的设备对象加入到记录devices的链表后就去查找那条记录drivers链表,看看有没有能够驱动这个设备的驱动,如果有驱动对象和设备对象就互相指向,这样驱动就能为该设备服务。如果没有找到驱动呢?很简单,设备不工作呗。这个设备就只好等待自己需要的驱动被加载,驱动会去找他。反过来说,驱动可能在设备插入之前被加载,同样的,驱动没有在记录devices的链表上找到她要服务的设备,驱动也就只好等待设备被插入的时候来找她。

    所以,之前所想的driver_register()函数会调用drv->probe的想法是错的,仅仅只是注册而已,只有当有设备插入时才会调用drv->probe,它专门是用来插入设备后对设备的操作的,而不是在没有设备插入时一个人在YY

  • 相关阅读:
    HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
    Octavia 的 HTTPS 与自建、签发 CA 证书
    Octavia 创建 loadbalancer 的实现与分析
    OpenStack Rally 质量评估与自动化测试利器
    自建 CA 中心并签发 CA 证书
    Failed building wheel for netifaces
    通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
    OpenStack Placement Project
    我们建了一个 Golang 硬核技术交流群(内含视频福利)
    没有图形界面的软件有什么用?
  • 原文地址:https://www.cnblogs.com/AlwaysOnLines/p/3832649.html
Copyright © 2011-2022 走看看