专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »嵌入式开发 » linux网络配置:Linux下USB设备的原理、配置、常见问题 »正文

linux网络配置:Linux下USB设备的原理、配置、常见问题

来源: 发布时间:星期四, 2008年12月11日 浏览:13次 评论:0
作者:赵明
V7kfbaiducukE0z来自:IBM DW
V7kfbaiducukE0z
V7kfbaiducukE0zUSB设备越来越多而Linux在硬件配置上仍然没有做到完全即插即用对于Linux怎样配置和使用他们也越来越成为困扰我们大问题本文着力从Linux系统下设备驱动架构去阐述怎样去使用和配置以及怎样编制USB设备驱动对于般用户可以使我们明晰Linux设备驱动方式为更好地配置和使用USB设备提供了方便;而对于希望开发Linux系统下USB设备驱动提供了初步学习USB驱动架构机会
V7kfbaiducukE0z前言
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0zUSB是英文"Universal Serial Bus"缩写意为"通用串行总线"是由Compaq(康柏)、DEC、IBM、Intel、NEC、微软以及Northern Telecom(北方电讯)等公司于1994年11月共同提出主要目就是为了解决接口标准太多弊端USB使用个4针插头作为标准插头并通过这个标准接头采用菊花瓣形式把所有外设连接起来它采用串行方式传输数据目前最大数据传输率为12Mbps, 支持多数据流和多个设备并行操作允许外设热插拔
V7kfbaiducukE0z
V7kfbaiducukE0z目前USB接口虽然只发展了2代(USB1.0/1.1USB2.0)但是USB综合了个多平台标准所有优点 -- 包括降低成本增加兼容性可连接大量外部设备融合先进功能和品质使其逐步成为PC接口标准进入了高速发展期
V7kfbaiducukE0z
V7kfbaiducukE0z那么对于使用Linux系统正确支持和配置常见USB设备就是其使用必不可少关键
V7kfbaiducukE0z
V7kfbaiducukE0z相关技术基础
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z模块(驱动
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z模块(module)是在内核空间运行实际上是种目标对象文件没有链接不能独立运行但是可以装载到系统中作为内核部分运行从而可以动态扩充内核功能模块最主要用处就是用来实现设备驱动
V7kfbaiducukE0z
V7kfbaiducukE0zLinux下对于个硬件驱动可以有两种方式:直接加载到内核代码中启动内核时就会驱动此硬件设备种就是以模块方式编译生成个.o文件当应用需要时再加载进内核空间运行所以我们所说个硬件驱动通常指就是个驱动模块
V7kfbaiducukE0z
V7kfbaiducukE0z设备文件
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z对于个设备它可以在/dev下面存在个对应逻辑设备节点这个节点以文件形式存在但它不是普通意义上文件它是设备文件更确切它是设备节点这个节点是通过mknod命令建立其中指定了主设备号和次设备号主设备号表明了某类设备般对应着确定驱动;次设备号般是区分不同属性例如不同使用方法不同位置不同操作这个设备号是从/proc/devices文件中获得所以般是先有驱动在内核中才有设备节点在目录中这个设备号(特指主设备号)主要作用就是声明设备所使用驱动驱动和设备号是对应当你打开个设备文件时操作系统就已经知道这个设备所对应驱动
V7kfbaiducukE0z
V7kfbaiducukE0zSCSI 设备
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0zSCSI是有别于IDE个计算机标准接口现在大部分平板式扫描仪、CD-R刻录机、MO光磁盘机等渐渐趋向使用SCSI接口加之SCSI又能提供个高速传送通道所以接触到SCSI设备用户会越来越多Linux支持很多种SCSI设备例如:SCSI硬盘、SCSI光驱、SCSI磁带机更重要Linux提供了IDE设备对SCSI模拟(ide-scsi.o模块)我们通常会就把IDE光驱模拟为SCSI光驱进行访问在Linux中很多软件都只能操作SCSI光驱例如大多数刻录软件、些媒体播放软件通常我们USB存储设备也模拟为SCSI硬盘而进行访问
V7kfbaiducukE0z
V7kfbaiducukE0zLinux硬件驱动架构
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z对于个硬件Linux是这样来进行驱动:首先我们必须提供个.o驱动模块文件(这里我们只说明模块方式其实内核方式是类似我们要使用这个驱动首先要加载运行它(insmod *.o)这样驱动就会根据自己类型(设备类型或块设备类型例如鼠标就是设备而硬盘就是块设备)向系统注册注册成功系统会反馈个主设备号这个主设备号就是系统对它标识(例如硬盘块设备在/proc/devices中显示主设备号为3 我们用ls -l /dev/had看到主设备就肯定是3)驱动就是根据此主设备号来创建般放置在/dev目录下设备文件(mknod命令用来创建它它必须用主设备号这个参数)在我们要访问此硬件时就可以对设备文件通过open、read、write等命令进行而驱动就会接收到相应read、write操作而根据自己模块中相应进行了
V7kfbaiducukE0z
V7kfbaiducukE0z其中还有几个比较有关系东西:个是/lib/modules/2.4.XX目录它下面就是针对当前内核版本模块只要你模块依赖关系正确(可以通过depmod设置)你就可以通过modprobe 命令加载而不需要知道具体模块文件位置 另个是/etc/modules.conf文件它定义了些常用设备别名系统就可以在需要此设备支持时正确寻找驱动模块例如alias eth0 e100就代表第块网卡驱动模块为e100.o他们关系图如下:
V7kfbaiducukE0z
V7kfbaiducukE0z [ 相关贴图 ]
V7kfbaiducukE0z
V7kfbaiducukE0z配置USB设备
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z内核中配置.
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z要启用 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 开始感到困惑地方
V7kfbaiducukE0z
V7kfbaiducukE0z要理解"EHCI"及其同类是什么首先要知道每块支持插入 USB 设备主板或 PCI 卡都需要有 USB 主控制器芯片组这个特别芯片组与插入系统 USB 设备进行相互操作并负责处理允许 USB 设备与系统其它部分通信所必需所有低层次细节
V7kfbaiducukE0z
V7kfbaiducukE0zLinux 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设备) 
V7kfbaiducukE0z
V7kfbaiducukE0z启用了"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"
V7kfbaiducukE0z
V7kfbaiducukE0z旦用新已启用 USB 内核重新引导后若/proc/bus/usb下没有相应USB设备信息应输入以下命令将 USB 设备文件系统手动挂装到 /proc/bus/usb:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z# mount -t usbdevfs none /proc/bus/usb 
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z为了在系统引导时自动挂装 USB 设备文件系统请将下面行添加到 /etc/fstab 中 /proc 挂装行之后:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0znone /proc/bus/usb usbdevfs defaults 0 0 
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z模块配置方法.
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z在很多时候我们USB设备驱动并不包含在内核中其实我们只要根据它所需要使用模块加载就可以使它启作用
V7kfbaiducukE0z
V7kfbaiducukE0z首先要确保在内核编译时以模块方式选择了相应支持这样我们就应该可以在/lib/modules/2.4.XX目录看到相应.o文件在加载模块时我们只需要运行modprobe xxx.o就可以了(modprobe主要加载系统已经通过depmod登记过模块insmod般是针对具体.o文件进行加载)
V7kfbaiducukE0z
V7kfbaiducukE0z对应USB设备下面些模块是关键
V7kfbaiducukE0z
V7kfbaiducukE0zusbcore.o 要支持usb所需要最基础模块 
V7kfbaiducukE0zusb-uhci.o (已经提过) 
V7kfbaiducukE0zusb-ohci.o (已经提过) 
V7kfbaiducukE0zuhci.o 另个uhci驱动我也不知道有什么用般不要加载会死机 
V7kfbaiducukE0zehci-hcd.o (已经提过 usb2.0) 
V7kfbaiducukE0zhid.o USB人机界面设备像鼠标呀、键盘呀都需要 
V7kfbaiducukE0zusb-storage.o USB存储设备U盘等用到 
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z相关模块
V7kfbaiducukE0z
V7kfbaiducukE0zide-disk.o IDE硬盘 
V7kfbaiducukE0zide-scsi.o 把IDE设备模拟SCSI接口 
V7kfbaiducukE0zscsi_mod.o SCSI支持 
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z注意kernel config其中项:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z Probe all LUNs on each SCSI device
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z最好选上要不某些同时支持多个口读卡器只能显示若模块方式就要带参数安装或提前在/etc/modules.conf中加入以下项来支持多个LUN
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z add options scsi_mod max_scsi_luns=9  
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0zsd_mod.o SCSI硬盘 
V7kfbaiducukE0zsr_mod.o SCSI光盘 
V7kfbaiducukE0zsg.o SCSI通用支持(在某些探测U盘、SCSI探测中会用到) 
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z常见USB设备及其配置
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z在Linux 2.4内核中已经支持不下20种设备它支持几乎所有通用设备如键盘、鼠标、modem、打印机等并不断地添加厂商新设备象数码相机、MP3、网卡等下面就是几个最常见设备介绍和使用方法:
V7kfbaiducukE0z
V7kfbaiducukE0zUSB鼠标:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z键盘和鼠标属于低速输入设备对于已经为用户认可PS/2接口USB键盘和USB鼠标似乎并没有太多更优越地方现在大部分鼠标采用了PS/2接口不过USB接口鼠标也越来越多两者相比各有优势:般来说USB鼠标接口带宽大于PS/2鼠标也就是说在同样时间内USB鼠标扫描次数就要多于PS/2鼠标这样在定位上USB鼠标就更为精确;同时USB接口鼠标默认采样率也比较高达到125HZ而PS/2接口鼠标仅有40HZ(Windows 9x/Me)或是60HZ(Windows NT/2000)
V7kfbaiducukE0z
V7kfbaiducukE0z对于USB设备你当然必须先插入相应USB控制器模块:usb-uhci.o或usb-ohci.o
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe usb-uhci
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0zUSB鼠标为了使其正常工作您必须先插入模块usbmouse.o和mousedev.o
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe usbmouse
V7kfbaiducukE0z modprobe mousedev
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z若你把HID input layer支持和input core 支持也作为模块方式安装那么启动hid模块和input模块也是必要
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe hid
V7kfbaiducukE0z modprobe input
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0zUSB键盘:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z我们现在使用键盘大多是PS/2USB键盘还比较少见但是下来发展键盘将向USB接口靠拢使用USB键盘基本上没有太多要求只需在主板BIOS设定对USB键盘支持就可以在各系统中完全无障碍使用而且更可以真正做到在即插即用和热插拔使用,并能提供两个USB连接埠:让您可以轻易地直接将具有USB接头装置接在您键盘上而非计算机后面
V7kfbaiducukE0z
V7kfbaiducukE0z同样你当然必须先插入相应USB控制器模块:usb-uhci.o或usb-ohci.o
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe usb-uhci
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z然后您还必须插入键盘模块usbkbd.o以及keybdev.o这样usb键盘才能够正常工作此时运行系统命令:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0zmodprobe usbkbd
V7kfbaiducukE0zmodprobe keybdev
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z同样若你把HID input layer支持和input core 支持也作为模块方式安装那么启动hid模块和input模块也是必要
V7kfbaiducukE0z
V7kfbaiducukE0zU盘和USB读卡器:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z数码存储设备现在对我们来说已经是相当普遍CF卡、SD卡、Memory Stick等存储卡已经遍及我们身边通常他们读卡器都是USB接口另外很多MP3、数码相机也都是USB接口和计算机进行数据传递更我们U盘、USB硬盘作为移动存储设备已经成为我们必须装备
V7kfbaiducukE0z
V7kfbaiducukE0z在Linux下这些设备通常都是以种叫做usb-storage方式进行驱动要使用他们必须加载此模块
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe usb-storage
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z当然usbcore.o 和usb-uhci.o或usb-ohci也肯定是不可缺少另外若你系统中SCSI支持也是模块方式那么下面模块也要加载
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z modprobe scsi_mod
V7kfbaiducukE0z modprobe sd_mod
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z在加载完这些模块后我们插入U盘或存储卡就会发现系统中多了个SCSI硬盘通过正确地mount它就可以使用了(SCSI硬盘般为/dev/sd?可参照文章后面常见问题解答)
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z mount /dev/sda1 /mnt
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0zLinux支持其他USB设备
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0zMODEM--(比较常见) 
V7kfbaiducukE0z网络设备 
V7kfbaiducukE0z摄像头--(比较常见)例如ov511.o 
V7kfbaiducukE0z联机线--可以让你两台电脑用USB线实现网络功能usbnet.o 核在支持USB2.0标准上存在问题在其他版本Linux中均不存在此问题
V7kfbaiducukE0z
V7kfbaiducukE0z解决办法:在lilo或grub启动时用命令行传递参数init=/sbin/init这样在启动后就不运行其他服务而直接启动shell然后运行 
V7kfbaiducukE0zmount -o remount,rw / 使/ 可写init直接启动系统默认只mount /为只读 
V7kfbaiducukE0z然后vi /etc/modules.config文件 
V7kfbaiducukE0z删除alias usb-controller1 ehci-hcd或前面加#注释掉 
V7kfbaiducukE0z然后mount -o remount,ro / 使/ 只读避免直接关机破坏文件系统 
V7kfbaiducukE0z然后就可以按Ctrl-Alt-Delete直接重启了 
V7kfbaiducukE0z或许你有更简单办法:换USB键盘和鼠标为PS2接口启动后修改/etc/modules.config文件 
V7kfbaiducukE0z
V7kfbaiducukE0z我们已经知道U盘在Linux中会模拟为SCSI设备去访问可怎么知道它对应那个SCSI设备呢?
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z方法1:推测通常你第次插入个SCSI设备它就是sda第二个就是sdb以此类推你启动Linux插入个U盘就试试sda换了个就可能是sdb这里注意两个特例:1) 你用是联想U盘它可能存在两个设备区(个用于加密或启动电脑)这样就可能次用掉两个sda、sdb换个U盘就是sdc、sdd2) 联想数码电脑中可能已经有了六合读卡器它同样也是USB存储设备它会占掉个或两个SCSI设备号
V7kfbaiducukE0z
V7kfbaiducukE0z方法2:看信息其实只要你提前把usb-storage.o、scsi_mod.o、sd_mod.o模块加载(直接在kernel中也可以)了在你插入和拔出U盘时系统会自动打出信息如下:
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0zSCSI device sda: 60928 512- hdwr sectors ( 31 MB )
V7kfbaiducukE0zsda: Write Protect is on
V7kfbaiducukE0z
V7kfbaiducukE0z 
V7kfbaiducukE0z
V7kfbaiducukE0z根据此信息你就知道它在sda上了当然可能你系统信息级别比较高上述信息可能没有打出这时候你只要tail /var/log/messages就可以看到了
V7kfbaiducukE0z
V7kfbaiducukE0z方法3:同样cat /proc/partitions也可以看到分区信息其中sd?就是U盘所对应若根本没有sd设备就要检查你SCSI模块和usb-storage模块是否正确加载了
V7kfbaiducukE0z
V7kfbaiducukE0z在使用U盘或存储卡时我该mount /dev/sda还是/dev/sda1呢?
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z这是个历史遗留问题存储卡最初尺寸很小很多厂商在使用时就直接使用存储不含有分区表信息而随着存储卡尺寸不断扩大它也就引入了类似硬盘分区概念例如/dev/hda你可以分成主分区hda1、hda2扩展分区hda3然后把扩展分区hda3又分为逻辑分区hda5、hda6、hda7等这样通常U盘就被分成个分区sda1类似把硬盘整个分区分成个主分区hda1实际上我们完全可以通过fdisk /dev/sda对存储卡进行完全类似硬盘分区方式分成sda1、sda2甚至逻辑分区sda5、sda6实际上对USB硬盘目前你确需要这样它通常都是多少G容量而且通常它里面就是笔记本硬盘
V7kfbaiducukE0z
V7kfbaiducukE0z个好玩问题你在Linux下用fdisk /dev/sda 对U盘进行了多分区这时候到windows下你会发现怎么找怎么格式化U盘都只能找到第个分区大小尺寸而且使用看不出任何问题这主要是windows驱动对U盘都只支持个分区缘故你是不是可以利用它来进行些文件隐藏和保护?你是不是可以和某些人没玩过Linux人开些玩笑:你U盘容量变小了J
V7kfbaiducukE0z
V7kfbaiducukE0z现在较多数码设备也和windows是把所有U盘容量分为所以在对待U盘时候通常你mount是sda1但对于某些特殊数码设备格式化U盘或存储卡(目前我发现款联想支持模拟USB软盘U盘和我个数码相机)你就要mount /dev/sda它根本就没分区表(若mount /dev/sda1通常效果是死掉)其实这些信息只要你注意了/proc/partitions文件都应该注意到
V7kfbaiducukE0z
V7kfbaiducukE0z每次插入U盘都要寻找对应设备文件名都要手动mount我能不能做到象windows那样插入就可以使用呢
V7kfbaiducukE0z
V7kfbaiducukE0z
V7kfbaiducukE0z当然可以不过你需要做些工作我这里只提供些信息帮助你去尝试完成设置:Linux内核提供了种叫hotplug支持东西它可以让你系统在PCI设备、USB等设备插拔时做些事情而automount 功能可以使你软驱、光盘等设备分区自动挂载和自动卸载你甚至可以在KDE桌面中创建相应图标方便你操作具体设置方法就要你自己去尝试了反正我使用Linux已经麻木了不就是敲行命令嘛

V7kfbaiducukE0z
V7kfbaiducukE0z

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: