.0 CardReader CF 0100 /dev/sdb /dev/sg2
[2:0:0:1] disk USB2.0 CardReader SM XD 0100 /dev/sdc /dev/sg3
[2:0:0:2] disk USB2.0 CardReader MS 0100 /dev/sdd /dev/sg4
[2:0:0:3] disk USB2.0 CardReader SD 0100 /dev/sde /dev/sg5
[3:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdf /dev/sg6
除了通常的块设备文件外,每个条目在最后一列1中列出SCSI通用设备文件。例如,位于/dev/sr0的光驱的通用设备是/dev/sg1。
为什么你想使用一个通用设备?答案是与内核中代码的复杂性有关。随着任务变得越来越复杂,最好把它们留在内核之外。考虑一下CD/DVD的写入和读取。读取光盘是相当简单的操作,而且有专门的内核驱动。
然而,写光盘要比读光盘困难得多,而且没有关键的系统服务依赖于写光盘的操作。没有理由用这种活动来威胁内核空间。因此,要在Linux中写入光盘,你需要运行一个用户空间程序,与一个通用的SCSI设备对话,比如/dev/sg1。这个程序可能比内核驱动的效率低一些,但它更容易建立和维护。
3.6.4 单一设备的多种访问方法
图3-3展示了Linux SCSI子系统从用户空间访问光驱的两个点(sr和sg)(SCSI下层的任何驱动都被省略了)。进程A使用sr驱动从驱动器中读取,进程B使用sg驱动向驱动器写入。然而,像这样的进程通常不会同时运行来访问同一个设备。
图3-3:光学设备驱动原理图
在图3-3中,进程A从块设备中读取数据。但是,用户进程真的会以这种方式读取数据吗?通常情况下,答案是否定的,不是直接的。在块设备上面还有更多的层,甚至还有更多的硬盘访问点,你将在下一章中学习。