Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2153372
  • 博文数量: 333
  • 博客积分: 10161
  • 博客等级: 上将
  • 技术积分: 5238
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-19 08:59
文章分类

全部博文(333)

文章存档

2017年(10)

2014年(2)

2013年(57)

2012年(64)

2011年(76)

2010年(84)

2009年(3)

2008年(37)

分类: LINUX

2008-09-01 10:11:56

Linux下设备完全驱动之四

尽管各种数码设备越来越多,但是Linux在对它们的配置上还没有做到像Windows一样方便,很多人正是因为心爱的数码相机无法在Linux下使用,而不得不保留一个Windows系统。所以,掌握如优盘、移动硬盘、数码相机等设备在Linux下的驱动方法,对于熟练使用Linux而言是必备的技能。

这一讲将会介绍常见USB、IEEE1394、PCMCIA等移动设备的驱动概念和安装技巧,为读者更好地配置和使用这些设备提供帮助。

USB设备驱动概述

USB 是通用串行总线(Universal Serial Bus),是在1994年由Intel、NEC、微软和IBM等公司共同提出的。USB的目的在于将众多的接口(串口、并口、PS2口等),改为通用的标准。它仅仅使用一个4针插头作为标准插头,并通过这个标准接头连接各种外设,如鼠标、键盘、游戏手柄、打印机、数码相机等。USB接口的特点是支持热插拔,支持单接口上接多个设备等。

USB的优点此处不再赘述,我们主要来看一看Linux对USB的支持。USB采用串行方式传输数据,USB 1.1最大数据传输率为12Mbps,Linux内核为2.4以上版本都可以支持。

USB 2.0规范是由USB 1.1规范演变而来的,它理论上速度较1.1提高了40倍,达到了480Mb/s,但目前常见的USB 2.0设备只能达到理论值的一半。 Linux内核2.4.19版本开始对USB 2.0进行支持。

除了内核的版本要对USB接口进行支持之外,还要确定目前的系统是否编译了USB的驱动模块。如果让Linux系统支持USB设备,还需要一些驱动模块。我们都知道内置的驱动程序一般都在 /lib/modules/2.4XXX/kernel/drivers目录中。这个目录中会有usb及几个子目录,可以从中找到以下的几个USB关键基础模块:

usbcore.o 所有USB设备都需要的基本驱动模块;

host/ehci-hcd.o USB 2.0设备支持;

host/usb-uhci.o Intel VIA等芯片组USB部分的驱动;

host/usb-ohci.o iMac、SiS、Ali等非Intel芯片组USB部分的驱动;

storage/usb-storage.o USB接口的存储设备,如移动硬盘、U盘等都会用到;

hid.o USB接口的键盘、鼠标等人机交互设备的基础支持。

在该目录下还有一些具体设备的驱动程序,分别驱动不同设备:

[pre]# ls -p /lib/modules/2.4.21-4.EL/kernel/drivers/usb/         acm.o     CDCEther.o hpusbscsi.o microtek.o   rtl8150.o usbcore.o   wacom.o         audio.o   dabusb.o   kaweth.o   pegasus.o   scanner.o usb-midi.o         brlvger.o hid.o     kbtab.o     powermate.o serial/   usbnet.o         catc.o   host/     mdc800.o   printer.o   storage/   uss720.o[/pre]

usb-storage.o USB对与存储部分的驱动模块;

scsi_mod.o 对SCSI设备的支持;

sd_mod.o 对SCSI硬盘支持模块,针对USB硬盘;

sr_mod.o 对SCSI光盘支持模块,针对USB光驱;

sg.o SCSI序列的通用支持模块;

ide-scsi.o 该模块可以把IDE设备模拟成SCSI接口。

通过查看/lib/modules/2.XXX/modules.dep文件,可以查看上述这些模块是否存在。一般情况下这些模块已经被编译,否则需要重新编译内核模块。

在正确地装载了驱动以后,可以通过访问/dev/sd?设备来访问优盘或移动硬盘。通常情况下,通过访问sda1来访问移动硬盘或优盘的第一个分区。在USB基本驱动存在的情况下插入优盘,就可以看到如下信息:

[pre]usb.c: USB device 7 (vend/prod 0xea0/0x6803) is not claimed by any active driver.         Starting timer : 0 0         Vendor: Netac   Model: OnlyDisk   Rev: 1.11         Type:   Direct-Access   ANSI SCSI revision: 02         Starting timer : 0 0         Attached scsi removable disk sda at scsi0, channel 0, id 0, lun 0         SCSI device sda: 32256 512-byte hdwr sectors (17 MB)         sda: Write Protect is off[/pre]


上面这一段是usb-storage.o和SCSI驱动在起作用,我们可以看到优盘被认成是sda,要使用它可以先查看分区表:

[pre]# fdisk -l /dev/sda         Disk /dev/sda: 16 MB, 16515072 bytes         2 heads, 32 sectors/track, 504 cylinders         Units = cylinders of 64 * 512 = 32768 bytes         Device Boot   Start     End   Blocks   Id System         /dev/sda1   *       1     503   16080   1 FAT12         # mkdir /mnt/usb         # mount -t msdos /dev/sda1 /mnt/usb   该优盘得类型为FAT12[/pre]


之后就可以通过访问/mnt/usb来访问优盘了。注意,如果要拔掉优盘或移动存储设备,请先umount然后再拔出,这样可以保证数据全部被写入,否则系统会出错,数据可能不完整。

[pre]# umount /mnt/usb[/pre]

USB数码相机的驱动

数码相机类型繁多,但是在Linux下使用数码相机有比较简便的方法。我们知道USB接口是数码相机的主要接口,在Linux中访问数码相机,通常可以通过下面两种方法。

1.使用专门软件

Red Hat Linux中自带的gtkam软件是一个提供了数码照相机图形化界面的程序,它支持100多种数码相机。gtkam可以直接与数码照相机相连,允许直接打开、查看、并删除图像。在Red Hat 9.0的光盘中,有gtkam的RPM包:

[pre]# ls gtkam*         gtkam-XXXX.i386.rpm gtkam-gimp-XXXX.i386.rpm         # rpm -ivh --aid gtkam*         # rpm -ivh --aid --force gphoto2-XXXX.i386.rpm[/pre]


gtkam基于gphoto,有时无法使用gtkam的原因是因为gphoto没有安装或模块被覆盖,所以需要重新安装gphoto。安装完毕后,在X-Window中运行gtkam就可以看到如图1所示界面。

[pre]# gtkam[/pre]

图1 gtkam界面

在图1中,单击gtkam的“camera”→“Add Camera”可以添加数码相机,然后在弹出的窗体中单击“Detect”,测试数码相机的连接类型。最后单击“OK”,就可以看到数码相机中的照片了。

图2所示使用gtkam连接Kodak DX6340相机,看到存储卡中的照片。选择照片,单击保存就可以把照片保存到硬盘上。

我们也可以从获得gtkam的最新版本及源代码,下载后可以使用其中的install.sh来进行安装。

2.把数码相机当做是USB存储设备还有一种方式就是把数码相机当做是USB存储设备,如优盘、读卡器等,这样就可以像访问优盘那样来访问数码相机:


[pre]# mount -t vfat /dev/sda1 /mnt/usb[/pre]


但是,采用这种方式极有可能遇到不能支持的数码相机,比如笔者使用的Kodak DX6340数码相机,插入USB口之后出现以下信息:


[pre]usb.c: USB device 2 (vend/prod 0x40a/0x570)         is not claimed by any active driver.[/pre]


对这种问题的解决办法不只是可以驱动不支持的数码相机,像不支持的存储设备也都可以使用,比如优盘、读卡器等。

(1)使用lsmod确定USB基本驱动模块已经装载,如果没有使用以上的命令装载:


[pre]# modprobe ehci-hcd; modprobe usb-uhci;         modprobe usb-storage         # modprobe ide-scsi; modprobe scsi_mod;         modprobe sd_mod[/pre]


(2)使用cat /proc/bus/usb/devices得到当前系统USB总线上的设备信息,尤其注意Vendor、ProdID、Product等信息:


[pre]C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA         I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub         E: Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=255ms         T: Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0         D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1         P: Vendor=040a ProdID=0570 Rev= 1.00         S: Manufacturer=Eastman Kodak Company         S: Product=KODAK EasyShare DX6340 Zoom Digital Camera         S: SerialNumber=KCKCJ33400274[/pre]


数码相机也是一种存储设备,然而对于Linux下的移动存储设备都是通过usb-storage.o驱动的,然后模拟为 SCSI设备。如果数码相机无法使用,通常是usb-storage驱动未包括此厂商识别和产品识别信息(在类似skel_probe的USB最初探测时被屏蔽了)。对于USB存储设备的硬件访问部分,通常是一致的。所以,要支持数码相机,仅需要修改usb-storage中关于厂商识别和产品识别列表部分。

USB设备识别信息中重要的部分如下:


[pre]P: Vendor=040a ProdID=0570 Rev= 1.00         S: Manufacturer=Eastman Kodak Company         S: Product=KODAK EasyShare DX6340 Zoom Digital Camera[/pre]


若/proc/bus/usb下没有相应USB设备信息,应输入以下命令将USB设备文件系统手动挂装到/proc/bus/usb:


[pre]# mount -t usbdevfs none /proc/bus/usb[/pre]


(3)编辑drivers/usb/storage/unusual_devs.h文件。下面是所有已知的USB产品登记列表,格式如下:


[pre]UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax,         vendor_name,         product_name,         use_protocol, use_transport, init_function,         Flags).[/pre]


usb-storage.o就是根据这个列表来识别各种设备。这样,可以将刚才/proc/bus/usb/devices文件中得出的信息添加在上面,重新编译模块,让usb-storage驱动去认识和发现它。


[pre]UNUSUAL_DEV( 0x040a, 0x0570, 0x0001, 0x0001,         "Eastman Kodak Company",         "KODAK EasyShare DX6340 Zoom Digital Camera",         US_SC_SCSI, US_PR_CB, NULL,         US_FL_FIX_INQUIRY | US_FL_START_STOP | US_FL_MODE_XLATE ),[/pre]


注意,添加以上几句代码的位置一定要正确。经过比较发现,usb-storage驱动对所有注册都是按idVendor、 idProduct数值从小到大排列的,因此添加代码也要放在相应位置。

(4)重新编译模块,之后插入的数码相机就可以像其它优盘一样作为USB存储设备去访问。


[pre]# make dep         # make modules         # make modules_install[/pre]
USB摄像头的驱动

在内核源文件中,自带了一部分摄像头的驱动,目前大量的杂牌摄像头都可以使用OV511的驱动模块。如果USB摄像头无法使用,则可以试试重新编译模块。下面就以一个没有驱动程序的摄像头为例,尝试使用OV511驱动模块驱动。

1. 获取内核源码

先从Red Hat光盘或kernel.org获取当前版本的内核源码,并安装:


[pre]# rpm -ivh kernel-source-2.XXX.rpm[/pre]


或者


[pre]# tar zxvf linux-2.XXX.tar.gz[/pre]


2. 运行

到源码目录中运行:


[pre]# make menuconfig[/pre]


或者


[pre]# make xconfig //需要在X-Window下[/pre]


3. 选择USB的模块
选择USB的模块如图3所示。

选择要编译的驱动可以查看说明书,确定摄像头芯片是什么型号,如图4所示,选定OV511摄像头的支持。在USB support下可以选择多种驱动的模块,比如常用的OV511芯片的摄像头驱动、USB打印机的驱动等。

图3 编译内核选择USB support
图4 在USB support下可选择多种驱动模块

4. 保存、编译和安装


[pre]# make dep         # make modules         # make modules_install[/pre]


5. 加载驱动


[pre]# modprobe ehci-hcd         # modprobe usb-uhci         # modprobe ov511         cat /proc/devices[/pre]


接着运行gnomemeeting等工具,选择/dev/video0或/dev/video1作为摄像头设备文件,这样摄像头就可以使用了。

外置USB光驱及刻录机的驱动

USB光驱与其它的USB存储设备使用类似,只不过USB光驱会被识别为SCSI光驱,如/dev/sr0或/dev/scd0等设备,它需要sr_mod.o(SCSI CD-ROM设备)驱动模块。










[pre]# modprobe sr_mod //如果sr_mod模块没有编译,请重新编译内核,在SCSI部分         # mount -t iso9660 /dev/scd0 /mnt/cdrom[/pre]


关于外置刻录机驱动详见本刊今年第8期“Linux完全驱动(二)”:


[pre]# mkisofs -Jv -V examplecd -o example.iso /root/[/pre]


将/root/目录下的文件做成一个名叫example.iso的光盘镜像文件,该文件的卷标为examplecd;还可通过下面命令将该文件加载到/mnt/iso文件夹中。


[pre]# mkdir /mnt/iso         # mount -t iso9660 -o loop example.iso /mnt/iso[/pre]


在调整完/mnt/iso文件的内容后使用下面命令:


[pre]# umount /mnt/iso[/pre]


最后使用cdrecord命令刻录:


[pre]# cdrecord -scanbus[/pre]


查看SCSI总线中刻录机的配置信息:


[pre]Cdrecord 2.0 (i686-pc-linux-gnu) Copyright         (C) 1995-2002 J?rg Schilling         Linux sg driver version: 3.1.25         Using libscg version 'schily-0.7'         cdrecord: Warning: using inofficial         libscg transport code version         (schily - Red Hat-scsi-linux-sg.c-1.75-RH '@(#)scsi-linux-sg.c         1.75 02/10/21 Copyright 1997 J. Schilling').         scsibus0:         0,0,0   0) 'HL-DT-ST' 'RW/DVD GCC-4240N' 'E112' Removable CD-ROM         0,1,0   1) *         0,2,0   2) *         0,3,0   3) *         0,4,0   4) *         0,5,0   5) *         0,6,0   6) *         0,7,0   7) *[/pre]


从上面可以看到目前光驱在SCSI总线的参数,然后根据参数输入下面的命令刻录光盘:


[pre]# cdrecord -v -eject speed=24 dev=0,0,0 example.iso[/pre]


“speed=24”是以24速来刻录光盘,“dev=”后加上刚才显示的刻录机的SCSI参数。如果是外置DVD,则应使用dvdrecord命令,其用法与cdrecord相同。


[pre]# rpm -ivh dvdrecord-0.1.2-12.i386.rpm         # man dvdrecord 查看帮助[/pre]

USB鼠标和键盘的驱动

1.鼠标的驱动

在Red Hat Linux中,可以使用mouseconfig命令来配置鼠标,选择USB接口鼠标即可,如图5所示。


图5 使用mouseconfig配置USB接口鼠标
[pre]# mouseconfig[/pre]


如果使用手动的方式来配置,可以人工加入以下模块:

[pre]# modprobe hid         # modprobe input         # modprobe usbmouse         # modprobe mousedev[/pre]


2.USB键盘的驱动

[pre]# modprobe hid         # modprobe input         # modprobe usbkbd         # modprobe keybdev[/pre]

IEEE1394设备的驱动

IEEE1394 又称Firewire(火线)、i-Link(Sony的叫法),它跟USB接口类似,目前可以提供400Mb/s的带宽,虽然在理论上它较USB 2.0的480Mb/s的速度慢一些,但是在实际使用中,Firewire要比USB 2.0的设备快不少,所以仍然有很多设备配备这种接口,如DV(数字摄像机)和移动硬盘等。

与USB相比,Firewire的通用性不够强,得到的支持也较少。一般主板上不带该Firewire的芯片,通常是购买带1394接口的PCI卡来支持1394的设备。对于1394设备,Linux内核2.4.10之后的版本都可以支持。IEEE1394的驱动放在以下位置:

[pre]# ls /lib/modules/2.XXX/kernel/drivers/ieee1394         amdtp.o dv1394.o   ieee1394.o raw1394.o video1394.o         cmp.o   eth1394.o ohci1394.o sbp2.o[/pre]


IEEE1394 的驱动方式较USB大同小异,只是首先加载的是对1394总线的驱动(ieee1394.o)和1394芯片的驱动(ohci1394.o)。如果使用 1394卡连接DV,那么需要1394视频驱动(video1394.o)和DV视频I/O驱动(dv1394.o);如果需要访问的是1394外接硬盘或CD-ROM、刻录机等,则需要对SBP-2协议的支持(sbp2.o);如果使用1394接口的以太网卡,则需要加载驱动eth1394.o。

如果没有某种设备的驱动,则可以重新编译内核模块,选择以下模块:

[pre]# cd /usr/src/linux-2.XXX         # make xconfig[/pre]


选择其中的IEEE1394选项,如图6所示,然后重新编译模块:

[pre]# make dep         # make modules         # make modules_install[/pre]


驱动IEEE1394接口的硬盘或光驱时,需要预先加载的驱动有ieee1394.o和ohci1394.o:

[pre]# modprobe ohci1394[/pre]


上面代码会将两样驱动全部装载上,因为ohci1394依赖于ieee1394。

硬盘需要的驱动是sbp2.o,插入硬盘后它应该会自动加载。与USB设备相同,硬盘会被模拟成SCSI设备,请留意屏幕上显示的信息,看看是被模拟为sda还是其它的设备。使用以下命令使用硬盘:
[pre]# mkdir /mnt/1394         # mount -t vfat /dev/sda1 /mnt/1394[/pre]
IEEE1394光驱应该使用设备为/dev/scd0,如果在插入设备时没有自动加载,则可以试着手动加载sbp2模块及SCSI模块:

scsi_mod.o 对SCSI设备的支持; sd_mod.o 对SCSI硬盘支持模块,对应硬盘;

sr_mod.o 对SCSI光盘支持模块,对应光驱;

sg.o SCSI序列的通用支持模块。

IEEE1394光驱驱动与USB下相应的设备驱动非常相似,这里就不再赘述了。

现在各种移动设备层出不穷,花样繁多,目前国内网站上的资料不是很全,使用google搜索英文网站往往能得到许多自己需要的东西。

优盘或USB硬盘常见问题解决方法

1. 加载/dev/sda1时出错

这是因为较早的优盘不分区,它们使用/dev/sda,也有可能使用/dev/sda2或sda3等设备文件,请仔细观察fdisk -l /dev/sda的输出结果,看一看优盘的分区到底是哪一个。

2. 主机中已有SCSI或USB设备

主机中已经有SCSI或USB设备,比如/dev/sda硬盘或另一个优盘,这时可以尝试sdb或sdc等设备。实际上每一次在插入优盘时可以留意一下屏幕上显示的信息,那个优盘被转换成哪一个sd设备。

3. 优盘插入后没有反应,访问/dev/sd设备也没有反应

这时可以查看相关模块是否已经加载,如果没有加载可以手动加载,然后重新插入该设备,看看是否有反应:

[pre]# modprobe ehci-hcd; modprobe usb-uhci; modprobe usb-storage.o         # modprobe ide-scsi; modprobe scsi_mod.o; modprobe sd_mod.o[/pre]


4. 设备驱动已经加载,如何知道访问哪个设备文件

对比加载驱动前和加载驱动后的/proc/devices文件,多出的那一行就是这种驱动程序注册的主设备号。例如,对比OV511加载前后/proc/devices文件的变化,就会发现多出如下一行:

[pre]# cat /proc/devices         Character devices:         ...         81 video_capture         ...[/pre]


上面代码表示C型设备、主设备号为81的设备文件是访问OV511驱动的入口,再对照/usr/src/Documentation/devices.txt中查找C类型的主设备号81,就可以知道对应如下设备文件:

[pre]81 char     video4linux         0 = /dev/video0     Video capture/overlay device[/pre]


上面简要介绍了Linux下常用的USB、IEEE1394、PCMCIA设备驱动的安装与配置,希望能对读者安装与使用这些设备提供帮助。
阅读(3023) | 评论(0) | 转发(0) |
0

上一篇:Linux启动优化

下一篇:1752年9月的故事

给主人留下些什么吧!~~