
1
Linux 那些事儿之我是 U 盘
----------------------------------------------------------------------------------------------------------------------
摘要
2005 年 6 月,复旦大学微电子系本科毕业答辩上,老师问我:请你用一句话介绍一下 usb 技
术.我回了一句:老师,你有病吧,要能用一句话介绍我还费这么大劲写这么长的文章干嘛?
关键词:Linux, Kernel, 2.6, bus, usb, device driver, mass storage, scsi,
urb, bulk, control, host, pipe, command, 林志玲
----------------------------------------------------------------------------------------------------------------------
目录
引子 2
小城故事 3
MAKEFILE 不是 MAKE LOVE 4
变态的模块机制 6
想到达明天现在就要启程 9
未曾开始却似结束 11
狂欢是一群人的孤单 12
总线,设备,和驱动(上) 13
总线,设备,和驱动(下) 15
我是谁的他? 16
从协议中来,到协议中去(上) 19
从协议中来,到协议中去(中) 20
从协议中来,到协议中去(下) 23
梦开始的地方 24
设备花名册 27
冰冻三尺非一日之寒 32
冬天来了,春天还会远吗?(一) 36
冬天来了,春天还会远吗?(二) 41
冬天来了,春天还会远吗?(三) 45
冬天来了,春天还会远吗(四) 47
冬天来了,春天还会远吗?(五) 52
通往春天的管道 57
传说中的 URB 63
心锁 69
第一次亲密接触(一) 71
第一次亲密接触(二) 76

2
第一次亲密接触(三) 80
第一次亲密接触(四) 82
将控制传输进行到底 85
横空出世的 SCSI 88
谁是最变态的结构体 92
SCSI 数据结构-像雾像雨又像风 102
彼岸花的传说(一) 108
彼岸花的传说(二) 109
彼岸花的传说(三) 114
彼岸花的传说(四) 117
彼岸花的传说(五) 123
彼岸花的传说(六) 128
彼岸花的传说(七) 131
彼岸花的传说(八) 135
彼岸花的传说(THE END) 138
SCSI 命令之我型我秀 139
迷雾重重的 BULK 传输(一) 144
迷雾重重的 BULK 传输(二) 150
迷雾重重的 BULK 传输(三) 154
迷雾重重的 BULK 传输(四) 158
迷雾重重的 BULK 传输(五) 163
迷雾重重的 BULK 传输(六) 166
跟着感觉走(一) 171
跟着感觉走(二) 173
光荣属于苹果,属于诺基亚,属于摩托罗拉,属于索尼爱立信! 179
有多少爱可以胡来?(一) 182
有多少爱可以胡来?(二) 188
当梦醒了天晴了 193
其实世上本有路,走的人多了,也便没了路 198
引子
也许是在复旦养成了昼伏夜出的坏习惯,工作之后也总是很晚也不愿意睡.来到北京之后,开
始听广播听都市之声的北京不眠夜.这个节目是从 23 点直到第二天凌晨一点,我常常是听完
了才会睡觉.无论是北京还是上海,对我来说,生存总是那么困难,生活的压力总是那么大,每
天只有在这个节目中才能够寻找到一丝温暖.我不喜欢躺在床上听,而是喜欢一边听一边做
点别的事情,于是心血来潮的决定,写点文字吧,听着电波里别人分享心情,不妨也用文字来记
录自己的心情吧.
我首先想到的是写一些和 Linux相关的文字.事实上我并不喜欢 Linux,学习 Linux完全是一
种无奈,工作中要用,迫于生计,不得不去学习,而学习 Linux的过程中唯一让我觉得还有些乐
趣的是当遇到问题的时候可以去网上问去网上查,很多人写了很多文档可以让我们这些菜鸟
们参考学习,这样才让我们在工作中走了很多弯路.挺感谢那些分享自己知识的人.碰巧最近

3
我也看了点冬冬,并且这些冬冬在网上的资料也比较少,所以我想我不妨也把自己那一夜的
收获写出来,或许以后也能给别人提供一些帮助,想想也是,整个 Linux社区不正是这样吗,像
陈奕迅唱的那样,”把一个人的温暖转移到另一个人的胸膛”.
我要写的是 Linux 设备驱动程序相关的,主要分析的是 Linux 中与 U 盘相关的那部分代码.
过去也没有看过,但是今年 4 月底的某一天,一个偶然的原因,我一时冲动就看了一遍.我们几
个同学在人大附近打麻将,打到夜深了,因为我们几人人住的位置都离得挺远的,各自回去都
得打车,于是决定不如去权金城开个房间,晚上就睡那得了.在权金城洗浴中心,和几个同学洗
浴过后,有人去按摩了,而我和另一个人则留在了房间里,无聊中,那位哥们见我带了电脑,说
他有部 A片,很不错,不是很大,所以他存在 U盘里的,他还挺逗的说这是 2008年北京奥运会
指定 A 片,问我有没有兴趣,这还用问,当然有兴趣了,于是立马打开电脑,插入 u 盘,然后不一
会我就傻了,因为我的电脑根本就不能识别 U盘,首先我的电脑比较旧,装的是双系统,一个是
Win 98,这个没办法,没有 U 盘驱动,另一个是 Linux,2.6 的内核,按理应该是支持 U 盘的,
问题是实际情况却是我没有看到 U盘,/dev/目录下面根本没有这么一个盘符,于是我没办法
了,一脸沮丧,而同学在旁边自然表示出了对 Linux 很鄙视的神情.
过了一会,他去看电视了,正好有英超,我却没有心情看电视,想想就觉得奇怪,怎么会不能使
用 U 盘呢,这不可能啊,一定是我自己对 Linux 下面的一些冬冬没有弄清楚,于是我决定好好
看看问题到底出在哪,记得当时看了一下/var/log/messages 这个日志文件里边好像记录
了一些信息,感觉像是一些错误信息,但是看不明白它到底在说什么.同学开始劝我,算了算了,
改天再看吧,这话我可不愿意听,不是说 Linux内核源代码是公开的吗,大不了看看源代码,搞
清楚工作原理了还怕问题不能解决?无非就是一些 C 代码而已,好歹哥们也是认真学过谭浩
强大哥那本 C 程序设计的.而且当初那本书课后习题老师基本上都让我们做了,虽说是参考
了那本习题解答的书,可就算写代码不行,读代码还是没问题吧,语法什么的基本上还是很清
楚的,什么判断结构循环结构,包括 goto 语句,还是记得的.
所以我就开始看了,正所谓梦想有多远,就能走多远.以前我只是玩 CS 玩仙剑的时候能够整
晚整晚不睡,但那个晚上,为了告诉我同学,Linux 下也能看 A 片,Linux 下遇到问题更适合自
己解决,我愣是从一点看到快天亮,终于把 drivers/usb/storage/目录下面一万余行的代码
给看了一遍.当然没有看得太仔细,但是很显然把整个原理搞清楚了,问题也很快得以解决.
所以此刻,我整理了一下思路,决定把那晚看的冬冬用文字记录下来.也算为了纪念那个不寻
常的夜晚吧.不过我估计这个篇幅不会短,因为光那一万余行的代码贴出来就得占许许多多
页了,所以这件事情也许会占用我不少时间,然而,还好,每晚有北京不眠夜的陪伴,而且,也许
当我把心思投入到写这个故事的时候,能够把那些压力那些烦恼那种孤独那种郁闷以及那种
对生活的绝望给暂时忘记些许.
小城故事
这个故事中使用的是 2.6.10的内核代码.Linux内核代码目录中, 所有去设备驱动程序有关的代
码都在 drivers/目录下面,在这个目录中我们用 ls 命令可以看到很多子目录.

4
localhost:/usr/src/linux-2.6.10/drivers # ls
Kconfig atm cdrom eisa ide macintosh message net parpo
rt s390 tc w1
Makefile base char fc4 ieee1394 mca misc nubus pci
sbus telephony zorro
acorn block cpufreq firmware input md mmc oprofile pcmci
a scsi usb
acpi bluetooth dio i2c isdn media mtd parisc pnp se
rial video
其中 usb 目录包含了所有 usb 设备的驱动,而 usb 目录下面又有它自己的子目录,进去看一下,
localhost:/usr/src/linux-2.6.10/drivers # cd usb/
locahost:/usr/src/linux-2.6.10/drivers/usb # ls
Kconfig Makefile README atm class core gadget host image input media
misc net serial storage usb-skeleton.c
注意到每一个目录下面都有一个 Kconfig 文件和一个 Makefile,这很重要.稍后会有介绍.
而我们的故事其实是围绕着drivers/usb/storage这个目录来展开的.实际上这里边的代码清清
楚楚地展示了我们日常频繁接触的 U 盘是如何工作的,是如何被驱动起来的.但是这个目录里边
的冬冬并不是生活在世外桃源,他们总是和外面的世界有着千丝万缕的瓜葛.可以继续进来看一
下,
localhost:/usr/src/linux-2.6.10/drivers/usb # cd storage/
localhost:/usr/src/linux-2.6.10/drivers/usb/storage # ls
Kconfig debug.c freecom.c isd200.c protocol.c sddr09.c shuttle_usbat
.c unusual_devs.h
Makefile debug.h freecom.h isd200.h protocol.h sddr09.h shuttle_usba
t.h usb.c
datafab.c dpcm.c initializers.c jumpshot.c scsiglue.c sddr55.c transport.c
usb.h
datafab.h dpcm.h initializers.h jumpshot.h scsiglue.h sddr55.h transport.h
咋一看,着实吓了一跳,用`wc -l *`这个命令统计一下,12076 行,晕死...
但是,也许,生活中总是充满了跌宕起伏.
认真看了一下 Makefile 和 Kconfig 之后,心情明显好了许多.
Makefile 不是 Make Love
出来混,迟早要还的.
从前在复旦,混了四年,没有学到任何东西,每天就是逃课,上网,玩游戏,睡觉.毕业的时候,身边的
人读研的读研,出国的出国,找工作的吧,去麦肯锡的去麦肯锡,去 IBM 的去 IBM.而自己却一无所
长,没有任何技能,直到这时候才发现那四年欠了很多债,早知今日,何必当初.幸运的是,我还有一

5
张复旦的文凭,依靠着这张文凭,混进了 Intel.然而,工作以后,更是发现当初在校期间没有好好读
书其实真是在欠债,当初没学,工作以后还是要学,的确是迟早要还的,逃是逃不掉的.
毕业的时候,人家跟我说 Makefile 我完全不知,但是一说 Make Love 我就来劲了.现在想来依然
觉得丢人.
基本上,Linux 内核中每一个目录下边都有一个 Makefile,Makefile 和 Kconfig 就像一个城市的
地图,地图带领我们去认识一个城市,而 Makefile 和 Kconfig 则可以让我们了解这个目录下面的
结构.drivers/usb/storage/目录下边的 Makefile 内容如下:
#
# Makefile for the USB Mass Storage device drivers.
#
# 15 Aug 2000, Christoph Hellwig <hch@infradead.org>
# Rewritten to use lists instead of if-statements.
#
EXTRA_CFLAGS := -Idrivers/scsi
obj-$(CONFIG_USB_STORAGE) += usb-storage.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o
usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e) += shuttle_usbat.o
usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o
usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o
usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM) += dpcm.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o
usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o
usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
initializers.o $(usb-storage-obj-y)
关于 Kconfig 文件,在故事的最后会介绍,此刻暂且不表,Kconfig 文件比较长,就不贴出来了.但
是通过看 Kconfig 文件,我们可以知道,除了 CONFIG_USB_STORAGE 这个编译选项是我们真
正需要的以外,别的选项我们都可以不予理睬.比如,关于
CONFIG_USB_STORAGE_DATAFAB,Kconfig 文件中有这么一段,
config USB_STORAGE_DATAFAB
bool "Datafab Compact Flash Reader support (EXPERIMENTAL)"
depends on USB_STORAGE && EXPERIMENTAL
help
Support for certain Datafab CompactFlash readers.
Datafab has a web page at <http://www.datafabusa.com/>.
显然,这个选项和我们没有关系,首先这是专门针对 Datafab公司的产品的,其次 CompactFlash
reader 是一种 flash设备,但这显然不是 U盘,因为 drivers/usb/storage 这个目录里边的代码
是针对一类设备的,不是某一种特定的设备,这一类设备就是 usb mass storage 设备,关于这类
设备,有专门的文档进行介绍,有相应的 spec,描述这类设备的通信或者物理上电特性上等方面的
评论0