Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

你 扪心自问,你对得起谭浩强大哥吗?在谭浩强大哥的带领下我们学会了用 #include->main()->printf()来打印hello,world!从而向全世界展示了我们懂C 语言.而stdio.h 就是一个C 库,printf 是一个函数,来自函数库,可是内核中没有标准C 库,所以 开发者们自己准备了一些函数,专门用于内核代码中,所以就出来了一个printk,printk 的"k"就 是kernel,内核.所以我们只要把它当作printf 的兄弟即可,如果感兴趣,可以去研究一下printk 的特点,她和printf 多少有些不同,但基本思想是一样的.所以我们就不多讲了,当然驱动程序中 所 有的printk 语句对U 盘的工作都没有什么用,她无非是打出来给我们看的,或者说打印给用户 看, 或者呢,打印给开发者看,特别是开发者要调试程序的时候,就会很有用. 于是我们更开心了,不用看printk 的话,那就只有一个函数调用了,usb_register.这个函数是干 嘛的?首先这个函数正是来自usb core.凡是usb 设备驱动,都要调用这个函数来向usb core 注 册,从而让usb core知道有这么一个设备.这就像政府规定,一对夫妻结婚要到相关部门那里去登 记是一样的,我们无需知道政府是如何管理的,只需要知道去政府那里登记即可. 这样,insmod 的时候,usb_stor_init 这个函数会被调用,初始化就算完成了.于是设备就开始 工 作了...而当我们rmmod的时候,usb_stor_exit 这个函数会被调用,我们发现,这个函数也很短, 我们能看出来,US_DEBUG 也就是打印一些咚咚,因此,这里实际上也就是调用了一个函数 usb_deregister(),她和usb_register()是一对,完成了注销的工作,从此设备就从usb core 中 消失了.于是我们惊人的发现,编写设备驱动竟是如此的简单,驱动程序真的就这么结束了?... 这一切,不禁让人产生了一种幻觉,让人分不清故事从哪里开始,又从哪里结束,一切都太短暂了. 仿佛开始在结束的时候开始,而结束却在开始的时候就早已结束. 真的吗? 答案是否定的.孔子已经教育过我们,不光要看懂代码,更要理解代码背后的哲学. 所以我们在继续之前,先来看看这里到底有什么哲学.而这,就是伟大的Linux Kernel 2.6 中的 统 一的设备模型. 12 我们并无意去详细介绍2.6 中的设备模型,但是不懂设备模型又怎能说自己懂设备驱动呢?读代 码的人,写代码的人,都要知道,什么是设备驱动?什么又是设备?设备和驱动之间究竟是什么关 系? 设备如何与计算机主机联系起来?我相信在中关村买盗版光盘的哥们儿也能回答这个问题.计算 机世界里,设备有很多种类,比如PCI 设备,比如ISA 设备,再比如SCSI 设备,再比如我们这里的 USB 设备.为设备联姻的是总线,是他把设备连入了计算机主机.但是与其说设备是嫁给了计算 机 主机,倒不如说设备是嫁给了设备驱动程序.很显然,在计算机世界里,无论风里雨里,陪伴着设备 的正是驱动程序. 唯一的遗憾是,计算机中的设备和驱动程序的关系却并非如可乐和拉环的关系那样,一对一.然而 世上又有多少事情总能如人愿呢. 狂欢是一群人的孤单 Linux 设备模型中三个很重要的概念就是总线,设备,驱动.即bus,device,driver,而实际上内核

中也定义了这么一些数据结构,他们是struct bus_type,struct device,struct device_driver, 这三个重要的数据结构都来自一个地方,include/linux/device.h.我们知道总线有很多种,pci 总线,scsi 总线,usb 总线,所以我们会看到Linux 内核代码中出现 pci_bus_type,scsi_bus_type,usb_bus_type,他们都是struct bus_type 类型的变量.而 struct bus_type 结构中两个非常重要的成员就是struct kset drivers 和struct kset devices.kset 和另一个叫做kobject 正是Linux Kernel 2.6 中设备模型的基本元素,但此处 我 们却不愿多讲,因为暂时不用去认识他们.我们的生命中会遇见许许多多的人和事,但更多的人和 事与我们只是擦肩而过,只是我们生命中的过客而已.在我们人生的电影中,他们也许只有一个镜 头,甚至那一个镜头后来也被剪辑掉了.这里我们只需要知道,drivers 和devices 的存在,让 struct bus_type 与两个链表联系了起来,一个是devices 的链表,一个是drivers 的链表,也 就 是说,知道一条总线所对应的数据结构,就可以找到这条总线所关联的设备有哪些,又有哪些支持 这类设备的驱动程序. 而要实现这些,就要求每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向 总线汇报,或者说注册.比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一 个struct device 的变量,每一次有一个驱动程序,就要准备一个struct device_driver 结构的 变量.把这些变量统统加入相应的链表,device 插入devices 链表,driver 插入drivers 链表. 这 样通过总线就能找到每一个设备,每一个驱动. 然而,假如计算机里只有设备却没有对应的驱动,那么设备无法工作.反过来,倘若只有驱动却没有 设备,驱动也起不了任何作用.在他们遇见彼此之前,双方都如同路埂的野草,一个飘啊飘,一个摇 啊摇,谁也不知道未来在哪里,只能在生命的风里飘摇.于是总线上的两张表里就慢慢的就挂上了 那许多孤单的灵魂.devices 开始多了,drivers 开始多了,他们像是两个来自世界,devices 们 彼 此取暖,drivers 们一起狂欢,但他们有一点是相同的,都只是在等待属于自己的那个另一半. 看代码的我,一直好奇的想知道,他们是否和我们现实中一样,有些人注定是等别人,而有些人是注 定被人等的. 13 总线,设备,和驱动(上) struct bus_type 中为devices 和drivers 准备了两个链表,而代表device 的结构体struct device 中又有两个成员,struct bus_type *bus 和struct device_driver *driver,同样,代表 driver 的结构体struct device_driver 同样有两个成员,struct bus_type *bus 和struct list_head devices,struct device 和struct device_driver 的定义和struct bus_type 一 样, 在include/linux/device.h 中.凭一种男人的直觉,可以知晓,struct device 中的bus 记录的 是 这个设备连在哪条总线上,driver 记录的是这个设备用的是哪个驱动,反过来,struct device_driver 中的bus 代表的也是这个驱动属于哪条总线,devices 记录的是这个驱动支持 的 那些设备,没错,是devices(复数),而不是device(单数),因为一个驱动程序可以支持一个或多个 设备,反过来一个设备则只会绑定给一个驱动程序.

中也定义了这么一些数据结构,他们是struct bus_type,struct device,struct device_driver,<br />

这三个重要的数据结构都来自一个地方,include/linux/device.h.我们知道总线有很多种,pci<br />

总线,scsi 总线,usb 总线,所以我们会看到Linux 内核代码中出现<br />

pci_bus_type,scsi_bus_type,usb_bus_type,他们都是struct bus_type 类型的变量.而<br />

struct bus_type 结构中两个非常重要的成员就是struct kset drivers 和struct kset<br />

devices.kset 和另一个叫做kobject 正是Linux Kernel 2.6 中设备模型的基本元素,但此处<br />

我<br />

们却不愿多讲,因为暂时不用去认识他们.我们的生命中会遇见许许多多的人和事,但更多的人和<br />

事与我们只是擦肩而过,只是我们生命中的过客而已.在我们人生的电影中,他们也许只有一个镜<br />

头,甚至那一个镜头后来也被剪辑掉了.这里我们只需要知道,drivers 和devices 的存在,让<br />

struct bus_type 与两个链表联系了起来,一个是devices 的链表,一个是drivers 的链表,也<br />

就<br />

是说,知道一条总线所对应的数据结构,就可以找到这条总线所关联的设备有哪些,又有哪些支持<br />

这类设备的驱动程序.<br />

而要实现这些,就要求每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向<br />

总线汇报,或者说注册.比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一<br />

个struct device 的变量,每一次有一个驱动程序,就要准备一个struct device_driver 结构的<br />

变量.把这些变量统统加入相应的链表,device 插入devices 链表,driver 插入drivers 链表.<br />

这<br />

样通过总线就能找到每一个设备,每一个驱动.<br />

然而,假如计算机里只有设备却没有对应的驱动,那么设备无法工作.反过来,倘若只有驱动却没有<br />

设备,驱动也起不了任何作用.在他们遇见彼此之前,双方都如同路埂的野草,一个飘啊飘,一个摇<br />

啊摇,谁也不知道未来在哪里,只能在生命的风里飘摇.于是总线上的两张表里就慢慢的就挂上了<br />

那许多孤单的灵魂.devices 开始多了,drivers 开始多了,他们像是两个来自世界,devices 们<br />

彼<br />

此取暖,drivers 们一起狂欢,但他们有一点是相同的,都只是在等待属于自己的那个另一半.<br />

看代码的我,一直好奇的想知道,他们是否和我们现实中一样,有些人注定是等别人,而有些人是注<br />

定被人等的.<br />

13<br />

总线,设备,和驱动(上)<br />

struct bus_type 中为devices 和drivers 准备了两个链表,而代表device 的结构体struct<br />

device 中又有两个成员,struct bus_type *bus 和struct device_driver *driver,同样,代表<br />

driver 的结构体struct device_driver 同样有两个成员,struct bus_type *bus 和struct<br />

list_head devices,struct device 和struct device_driver 的定义和struct bus_type 一<br />

样,<br />

在include/linux/device.h 中.凭一种男人的直觉,可以知晓,struct device 中的bus 记录的<br />

是<br />

这个设备连在哪条总线上,driver 记录的是这个设备用的是哪个驱动,反过来,struct<br />

device_driver 中的bus 代表的也是这个驱动属于哪条总线,devices 记录的是这个驱动支持<br />

的<br />

那些设备,没错,是devices(复数),而不是device(单数),因为一个驱动程序可以支持一个或多个<br />

设备,反过来一个设备则只会绑定给一个驱动程序.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!