分类:
2006-10-16 16:03:03
usb摄像头生产商一般都会提供摄像头windows下的驱动,但大多数厂家并不提供linux下的驱动。而我们能在linux下使用各种usb摄像头更依赖于全世界开源运动的志愿者们无偿编写的各种驱动程序。我所使用的也正是这样的驱动。
摄像头芯片是z-star公司生产的301b(设备编号为0AC8:301B)型号芯片。此公司生产的usb摄像头芯片占据了国内市场的70%以上,但遗 憾的是该公司没有编写针对linux的驱动。好在有一个名为spca5xx的开源项目提供了很多摄像头的驱动,z-star 的301b 也包括在内。
要使用spca5xx驱动,内核需要支持v4l(video for linux)接口。
在使用该驱动时开始我遇到了一个问题:ubuntu5.10使用的内核kernel 2.6.12.10已经自带了spca5xx模块,该模块是动态加载的,即开机时不加载此模块,当接上摄像头以后系统自动加载该模块。该模块加载成功以后 会在/dev 目录下生成一个video0文件,各种usb摄像头视频相关的程序即是通过读此/dev/video0文件来获取摄像头抓取的图像。而问题也正在此:每当 /dev/video0被读取时,系统马上死机。死机后鼠标和键盘均不能使用。开始我怀疑是支持图形界面的基本系统Xserver死机(Xserver crash),但是用ctrl + Alt + F1~F6来调用各tty控制台也不行,因此断定此死机为内核死机(kernel crash),既然死机情况与Xserver无关,从而可以认为其它使用相同内核的linux发行版也应该会有类似的情况。造成死机的原因肯定是 spca5xx模块与内核某些功能发生冲突,因为spca5xx模块是建立在usbhost模块基础之上,故而也有可能是spca5xx与相应的usb驱 动模块有冲突。在google上查询关于读/dev/video0文件时kernel crash的资料,果然在一个mail list中发现有人遇到完全一样的情况,但他使用的内核是2.4.10,别人提供的相应解决方案是在内核的usb host controller功能模块中用uhci.o模块 替代usb-uhci.o模块。那么这个方案能否使用在kernel 2.6.12.10中呢?我查询了存放实现usb host controller功能模块的目录:/lib/modules/2.6.12-10-686/kernel/drivers/usb/host/,发现 该目录下根本就没有uhci.ko 和usb-uhci.ko文件,取而代之的是uhci-hcd.ko 、ohci-hcd.ko 、ehci-hcd.ko三个文件。这说明kernel 2.6与kernel 2.4差异很大,用来解决kernel 2.4中问题的方案在kernel 2.6中已经不适用。既然spca5xx在kernel 2.4的时代都能用,为什么在kernel2.6反而不能用了呢?就在我一筹莫展的时候,一个新的念头跳了出来:会不会是当前内核使用的spca5xx的 版本正好不能支持kernel 2.6.12.10呢?也许是spca5xx版本太老了?
从网站将最新的驱动源码下载下来以后便可编译安装。
安装过程如下:
输入make
因为编译驱动程序是需要内核源代码的,如果make报错找不到内核源代码,则需先指定源代码路径。
Makefile中寻找内核源代码树(kernel source tree)的语句是:
KERNELDIR := /lib/modules/$(KERNEL_VERSION)/build,
用uname -r查看当前使用内核版本为:2.6.12-10-686,则进入/lib/modules/2.6.12-10-686/,创建一个指向存放内核源代码目录的符号链接。
如果make再次报错为找不到 .config文件,是因为内核源代码没有configure过。进入源代码目录,输入make menuconfig进入配置内核编译选项的菜单界面,可以不做任何改动,直接保存退出,目的是为生成.config文件。
编译好spca5xx源代码以后,生成模块文件spca5xx.ko。这时需要先把原来已在内核中的模块卸载掉。
输入rmmod spca5xx.ko,卸载原有模块。
输入insmod (存放刚才编译的模块的路径)/spca5xx.ko,载入新的模块。
接上摄像头。
/dev/video0文件出现。
用camorama工具查看摄像头,看到了图像,没有死机,一切正常。
内核中配置.
要启用 Linux USB 支持,首先进入"USB support"节并启用"Support for USB"选项(对应模块为usbcore.o)。尽管这个步骤相当直观明了,但接下来的 Linux USB 设置步骤则会让人感到糊涂。特别地,现在需要选择用于系统的正确 USB 主控制器驱动程序。选项是"EHCI" (对应模块为ehci-hcd.o)、"UHCI" (对应模块为usb-uhci.o)、"UHCI (alternate driver)"和"OHCI" (对应模块为usb-ohci.o)。这是许多人对 Linux 的 USB 开始感到困惑的地方。
要理解"EHCI"及其同类是什么,首先要知道每块支持插入 USB 设备的主板或 PCI 卡都需要有 USB 主控制器芯片组。这个特别的芯片组与插入系统的 USB 设备进行相互操作,并负责处理允许 USB 设备与系统其它部分通信所必需的所有低层次细节。
Linux USB 驱动程序有三种不同的 USB 主控制器选项是因为在主板和 PCI 卡上有三种不同类型的 USB 芯片。"EHCI"驱动程序设计成为实现新的高速 USB 2.0 协议的芯片提供支持。"OHCI"驱动程序用来为非 PC 系统上的(以及带有 SiS 和 ALi 芯片组的 PC 主板上的)USB 芯片提供支持。"UHCI"驱动程序用来为大多数其它 PC 主板(包括 Intel 和 Via)上的 USB 实现提供支持。只需选择与希望启用的 USB 支持的类型对应的"?HCI"驱动程序即可。如有疑惑,为保险起见,可以启用"EHCI"、"UHCI" (两者中任选一种,它们之间没有明显的区别)和"OHCI"。(赵明注:根据文档,EHCI已经包含了UHCI和OHCI,但目前就我个人的测试,单独加EHCI是不行的,通常我的做法是根据主板类型加载UHCI或OHCI后,再加载EHCI这样才可以支持USB2.0设备)。
启用了"USB support"和适当的"?HCI"USB 主控制器驱动程序后,使 USB 启动并运行只需再进行几个步骤。应该启用"Preliminary USB device filesystem",然后确保启用所有特定于将与 Linux 一起使用的实际 USB 外围设备的驱动程序。例如,为了启用对 USB 游戏控制器的支持,我启用了"USB Human Interface Device (full HID) support"。我还启用了主"Input core support" 节下的"Input core support"和"Joystick support"。
一旦用新的已启用 USB 的内核重新引导后,若/proc/bus/usb下没有相应USB设备信息,应输入以下命令将 USB 设备文件系统手动挂装到 /proc/bus/usb:
# mount -t usbdevfs none /proc/bus/usb
为了在系统引导时自动挂装 USB 设备文件系统,请将下面一行添加到 /etc/fstab 中的 /proc 挂装行之后:
none /proc/bus/usb usbdevfs defaults 0 0
模块的配置方法.
在很多时候,我们的USB设备驱动并不包含在内核中。其实我们只要根据它所需要使用的模块,逐一加载。就可以使它启作用。
首先要确保在内核编译时以模块方式选择了相应支持。这样我们就应该可以在/lib/modules/2.4.XX目录看到相应.o文件。在加载模块时,我们只需要运行modprobe xxx.o就可以了(modprobe主要加载系统已经通过depmod登记过的模块,insmod一般是针对具体.o文件进行加载)
对应USB设备下面一些模块是关键的。
usbcore.o 要支持usb所需要的最基础模块
usb-uhci.o (已经提过)
usb-ohci.o (已经提过)
uhci.o 另一个uhci驱动程序,我也不知道有什么用,一般不要加载,会死机的
ehci-hcd.o (已经提过 usb2.0)
hid.o USB人机界面设备,像鼠标呀、键盘呀都需YAO
摄像头(比较常见)例如ov511.o
modprobe ov511