Chinaunix首页 | 论坛 | 博客
  • 博客访问: 523010
  • 博文数量: 86
  • 博客积分: 1076
  • 博客等级: 准尉
  • 技术积分: 1018
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-02 19:15
文章分类

全部博文(86)

文章存档

2013年(15)

2012年(69)

2011年(2)

分类: LINUX

2012-05-04 10:05:23

     最近在ramdisk中 insmod Marvell8686 的SDWIFI的驱动libertas_sdio.ko时,总是报错:

  1. /modules # mmc0: new SDIO card at address 0001
  2. libertas_sdio mmc0:0001:1: firmware: requesting sd8686_helper.bin
  3. /modules # libertas: can

     很明显,意思是需要的固件找不到;而之前都是在nfs中运行的,里面的东西很多,都是前面的员工积累下来的,这个WIFI是可以正常加载的,现在做了个精简版的ramdisk,肯定是少了什么东西。之前,这个固件sd8686_helper.bin(有三个,不一一列出)是存放在lib/firmwore下面的,我将其拷贝到ramdisk中,但是一直没找到什么地方指定了这个路径。但是其实,问题并不是出在这里,而是与udev相关的一点知识,之前没有注意到。
     对比原来的nfs,之前是支持udev功能的,自然也包含了加载firmware的功能,原来的etc/udev/目录下是有个firmware.sh的脚本,这个里面指定了路径。

  1. #!/bin/sh -e
  2. FIRMWARE_DIRS="/lib/firmware/$(uname -r) /lib/firmware"
  3. err() {
  4.  echo "$@" >&2
  5.  logger -t "${0##*/}[$$]" "$@" 2>/dev/null || true
  6. }
  7. if [ ! -e /sys$DEVPATH/loading ]; then
  8.  err "udev firmware loader misses sysfs directory"
  9.  exit 1
  10. fi
  11. for DIR in $FIRMWARE_DIRS; do
  12.  [ -e "$DIR/$FIRMWARE" ] || continue
  13.  echo 1 > /sys$DEVPATH/loading
  14.  cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data
  15.  echo 0 > /sys$DEVPATH/loading
  16.  exit 0
  17. done
  18. echo -1 > /sys$DEVPATH/loading
  19. err "Cannot find firmware file '$FIRMWARE'"
  20. exit 1
     这里暂不对udev的问题做过多的说明,可以另行学习。那么,现在的ramdisk中没有udev功能,就可以通过hotplug功能实现固件的加载了。
方法一、
     由于系统中,
 
  1. / # cat /proc/sys/kernel/hotplug
  2. /sbin/hotplug
     如果没有hotplug,并且无法加载firmware,可以写一个/sbin/hotplug脚本(注意chmod)

  1. #!/bin/sh
  2. if [ "$FIRMWARE" != "" ]; then
  3. HOTPLUG_FW_DIR=/lib/firmware/
  4. echo 1 > /sys/$DEVPATH/loading
  5. cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
  6. echo 0 > /sys/$DEVPATH/loading
  7. fi
     此时,在/lib/firmware下放好固件,加载libertas_sdio.ko的时候,系统会发出uevent事件,会自动运行/sbin/hotplug,也就能正常加载驱动了。

  1. /modules # insmod libertas_sdio.ko
  2. libertas_sdio: Libertas SDIO driver
  3. libertas_sdio: Copyright Pierre Ossman
  4. marvell sd8686 wifi: power up.
  5. /modules # mmc0: new SDIO card at address 0001
  6. libertas_sdio mmc0:0001:1: firmware: requesting sd8686_helper.bin
  7. libertas_sdio mmc0:0001:1: firmware: requesting sd8686.bin
  8. libertas: 00:02:78:b8:e0:76, fw 9.70.3p24, cap 0x00000303
  9. libertas: wlan0: Marvell WLAN 802.11 adapter
方法二、
      另外,参照http://blog.chinaunix.net/uid-13889805-id-120361.html的博客,嵌入式设备中通常没有udev和firmware_helper,更好的,可以使用/sbin/mdev的功能,

  1. / # echo /sbin/mdev> /proc/sys/kernel/hotplug
  2. / # cat /proc/sys/kernel/hotplug
  3. /sbin/mdev

     这样,就不需要添加另外的脚本了,mdev包含了udev和firmware_helper功能,自然也可以正确加载固件了。
     为了让其开机自动启动,可以在/etc/profile文件下,增加一行

  1. /bin/echo /sbin/mdev > /proc/sys/kernel/hotplug
就不用每次手动运行了。
方法三、
     这个方法承载自方法二,其实在我们的内核make menuconfig的时候,是可以配置,用什么工具或者应用来响应内核的uevent事件的,例如这里改为/sbin/mdev

  1. Device Drivers --->
  2. Generic Driver Options --->
  3. (/sbin/mdev) path to uevent helper
也就是这边指定了/proc/sys/kernel/hotplug用什么来执行的。


    
参考:
        
阅读(4286) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~