Chinaunix首页 | 论坛 | 博客
  • 博客访问: 437966
  • 博文数量: 75
  • 博客积分: 556
  • 博客等级: 中士
  • 技术积分: 712
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-12 10:10
文章分类
文章存档

2015年(4)

2014年(4)

2013年(31)

2012年(8)

2011年(8)

2010年(20)

分类: Android平台

2013-03-02 18:07:04

转自http://blog.sina.com.cn/s/blog_5f35912f0100w1ap.html


自从接触android,已经移植了好几个wifi,每个都会遇到不同的问题,看来不同的硬件确实有很大的区别,这次又遇到了一些莫名其妙的问题,按照下面的文章终于解决了,但是悲剧的是,没有确定问题到底是出在哪里,由于项目紧张,目前就这样吧,有时间再好好研究研究,参考的文章如下:


手动加载驱动
####16th,Jul
驱动加载
modprobe libertas
modprobe libertas_sdio
加载第二行时出错拉
# modprobe libertas_sdio
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
model=0xb
sd8686_helper.bin sd8686.bin
init: untracked pid 958 exited
过了一会出现:
libertas: can't load helper firmware
libertas: failed to load helper firmware
libertas_sdio: probe of mmc2:0001:1 failed with error -2
但是用lsmod又能看到
# lsmod 
libertas_sdio 8776 0 - Live 0xbf022000
libertas 97416 1 libertas_sdio, Live 0xbf009000
usbserial 30256 0 - Live 0xbf000000

###使用insmod试一下
insmod /lib/modules/2.6.24.7/kernel/drivers/net/wireless/libertas/libertas.ko
insmod /lib/modules/2.6.24.7/kernel/drivers/net/wireless/libertas/libertas_sdio.ko
还是老样子

###发现系统中没有提到的文件fireware文件
从华恒的romfs/lib把fireware拷贝到 /nfs/rootfs/lib下
$$还是不行

###把fireware拷贝到system/etc/下面,终于可以加载了
如下:
# modprobe libertas_sdio
libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
model=0xb
sd8686_helper.bin sd8686.bin
init: untracked pid 714 exited
init: untracked pid 717 exited
libertas: eth1: Marvell WLAN 802.11 adapter

$$$建议
Title:Android INIT not loading firmware
android员工答:You need to run the insmod in a separate process launched by init. 

#########
理解原理
Android uses a modified wpa_supplicant (external/wpa_supplicant) daemon for wifi support which is controlled through a socket by hardware/libhardware_legacy/wifi/wifi.c (WiFiHW) that gets controlled from Android UI through android.net.wifi package from frameworks/base/wifi/java/android/net/wifi/ and it's corresponding jni implementation in frameworks/base/core/jni/android_net_wifi_Wifi.cpp Higher level network management is done in frameworks/base/core/java/android/net

1.在build/target/board/generic/BoardConfig.mk中增加
BOARD_WPA_SUPPLICANT_DRIVER := WEXT

2.打开调试信息--可选
默认是不打开调试的
2.1 modify external/wpa_supplicant/common.c and set wpa_debug_level = MSG_DEBUG
2.2 modify common.h and change #define wpa_printf from if ((level) >= MSG_INFO) to if ((level) >= MSG_DEBUG)

3.创建system/etc/wifi/wpa_supplicant.conf
有2种socket
一种是android private socket
ctrl_interface=eth1
update_config=1
ap_scan=1  ###取决于wifi驱动,如果不行,则改为0试试
另一种是unix 标准socket,这里先选用第二种
ctrl_interface=DIR=/data/system/wpa_supplicant GROUP=wifi
update_config=1
ap_scan=1  ###取决于wifi驱动,如果不行,则改为0试试

4在init.rc中增加以下语句

#@qiu
    mkdir /system/etc/wifi 0777 wifi wifi
    chmod 0777 /system/etc/wifi
    chmod 0777 /system/etc/wifi/wpa_supplicant.conf
    chown wifi wifi /system/etc/wifi/wpa_supplicant.conf
    
mkdir /data/misc/wifi 0777 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 0777 /data/misc/wifi
chmod 0777 /data/misc/wifi/wpa_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf

    # wpa_supplicant socket (unix socket mode)
    mkdir /data/system/wpa_supplicant 0777 wifi wifi
    chmod 0777 /data/system/wpa_supplicant
    chown wifi wifi /data/system/wpa_supplicant
#qiu@

##如果是private socket,则是
mkdir /system/etc/wifi 0777 wifi wifi
chmod 0777 /system/etc/wifi
chmod 0777 /system/etc/wifi/wpa_supplicant.conf
chown wifi wifi /system/etc/wifi/wpa_supplicant.conf

#wpa_supplicant control socket for android wifi.c (android private socket)
mkdir /data/misc/wifi 0777 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 0777 /data/misc/wifi
chmod 0777 /data/misc/wifi/wpa_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf

5.在init.rc中添加wpa_supplicant和dhcpcd启动服务
service wpa_supplicant /system/bin/wpa_supplicant -dd -Dwext -ieth1 -c /system/etc/wifi/wpa_supplicant.conf
group system wifi inet
disabled
oneshot
##如果是pricvate socket则需要在group上面增加一行:
socket wpa_eth1 dgram 777 wifi wifi

service dhcpcd /system/bin/dhcpcd -f /system/etc/dhcpcd/dhcpcd.conf -d eth1
group system dhcp wifi
disabled
oneshot


5.5增加/system/etc/dhcpcd/dhcpcd.conf文件内容
interface eth1
option subnet_mask, routers, domain_name_servers

6.把wifi驱动编译进内核
首先init.rc中增加
setprop wifi.interface "eth1"
setprop wlan.driver.status "ok"
其次在修改hardware/libhardware_legacy/wifi/wifi.c
新的out/target/product/generic/system/lib/libhardware_legacy.so---v2
在函数wifi_load_driver()的体的开头增加
//@qiu    
    LOGE("Weber@wifi driver loaded !");
    return 0;
//qiu@
在函数wifi_unload_driver()体的开头增加
//@qiu
    LOGE("Weber@wifi driver unloaded!");
    return 0;
//qiu@

####17th,Jul
把驱动从M改为*,得zImage-vvv39
开始启动:
加载firmware的时候出错
libertas: can't load helper firmware
libertas: failed to load helper firmware
libertas_sdio: probe of mmc2:0001:1 failed with error -2

看来是无法加载fireware

###尝试修改wifi.c让它自动加载模块
修改
#ifndef WIFI_DRIVER_MODULE_PATH1
#define WIFI_DRIVER_MODULE_PATH1         "/system/lib/modules/libertas.ko"
#endif
#ifndef WIFI_DRIVER_MODULE_PATH2
#define WIFI_DRIVER_MODULE_PATH2         "/system/lib/modules/libertas_sdio.ko"
#endif
#ifndef WIFI_DRIVER_MODULE_NAME1
#define WIFI_DRIVER_MODULE_NAME1         "libertas"
#endif
#ifndef WIFI_DRIVER_MODULE_NAME2
#define WIFI_DRIVER_MODULE_NAME2         "libertas_sdio"
#endif
并在此文件的后面代码中做一定修改,wifi_load_driver()函数中也做相应修改
编译得到libhardware_legacy.so---v3
 
-启动后在设置中点击wifi
串口显示如下,看来是能加载了
# libertas_sdio: Libertas SDIO driver
libertas_sdio: Copyright Pierre Ossman
model=0xb
sd8686_helper.bin sd8686.bin
init: untracked pid 954 exited
init: untracked pid 957 exited
libertas: eth1: Marvell WLAN 802.11 adapter
但是wifi图标下面显示wifi不可用
查看logcat的main:
 7899 E/WifiHW  (  708): Cannot access "/data/misc/wifi/wpa_supplicant.conf": Permission denied
 7900 E/WifiHW  (  708): Wi-Fi will not be enabled
 7901 W/WifiHW  (  708): Weber@wifi driver unloaded!
 7902 E/WifiService(  708): Failed to start supplicant daemon.
 7903 D/SettingsWifiEnabler(  791): Received wifi state changed from Enabling to Unknown

于是增加以下语句到init.rc
mkdir /data/misc/wifi 0770 wifi wifi
mkdir /data/misc/wifi/sockets 0770 wifi wifi
chmod 0770 /data/misc/wifi
chmod 0660 /data/misc/wifi/wpa_supplicant.conf
chown wifi wifi /data/misc/wifi
chown wifi wifi /data/misc/wifi/wpa_supplicant.conf
并且cp system/etc/wifi/wpa_supplicant.conf ./data/misc/wifi/

启动,终于能打开wifi,但还是无法打开网页
查看logcat
4564 E/wpa_supplicant(  917): Failed to read or parse configuration '/system/etc/wifi/wpa_supplicant.conf'.
4565 E/WifiHW  (  708): Unable to open connection to supplicant on "/data/system/wpa_supplicant/sta": No such file or directory
4566 D/WifiService(  708): ACTION_BATTERY_CHANGED pluggedType: 1
4899 E/WifiHW  (  708): Supplicant not running, cannot connect
5574 E/WifiHW  (  708): Supplicant not running, cannot connect
5575 V/WifiStateTracker(  708): Supplicant died unexpectedly
5576 D/dalvikvm(  934): DexOpt: load 3102ms, verify 1519ms, opt 24ms
5577 D/installd(  665): DexInv: --- END '/system/app/Browser.apk' (success) ---
5578 D/NetworkStateTracker(  708): setDetailed state, old =IDLE and new state=DISCONNECTED
5579 D/ConnectivityService(  708): ConnectivityChange for WIFI: DISCONNECTED/DISCONNECTED

##在init.rc中把wpa_supplicant.conf权限修改为777,
还是有错误:
5573 E/WifiHW  (  708): Unable to open connection to supplicant on "/data/system/wpa_supplicant/sta": No such file or director

##在init.rc中增加以下几条语句
    setprop wifi.interface "eth1"
    setprop wlan.driver.status "ok"
    setprop wlan.interface "eth1"
结果还是不行logcat显示
E/WifiHW (  708):Unable to open connection to supplicant on "/data/system/wpa_supplicant/eth1": No such file or directory

##在init.rc中dhcp服务启动是为eth1的增加wifi组权限
又出现新错误
如果开始就enable wifi就会出现以下错误:
E/WifiHW  (  709): Unable to open connection to supplicant on "/data/system/wpa_supplicant/eth1": Connection refused
因为这是开机默认启动wifi,如果不起动,错误则是和上一条相同

###18th,Jul
##尝试在wpa_supplicant.conf设置GROUP=system,还是不行,只好改回去

ls /data/system/wpa_supplicant/eth1 -l
srwxrwx---    1 1010     1010            0 Jul 18 08:22 /data/system/wpa_supplicant/eth1

# ls /data/system/wpa_supplicant/eth1 -l
srwxrwxrwx    1 1010     1010            0 Jul 18 08:22 /data/system/wpa_supplicant/eth1

###18th,Jul手动调试
# wpa_supplicant -dd -Dwext -ieth1 -c /system/etc/wifi/wpa_supplicant.conf&
# ioctl[SIOCSIWPMKSA]: Invalid argument《《《《输出的错误

# ls /data/system/wpa_supplicant/eth1 -l
srwxrwxrwx    1 1010     1010            0 Jul 18 13:14 /data/system/wpa_supplicant/eth1

#wpa_cli -i eth1 -p /data/system/wpa_supplicant
不知道该如何设置ap
bash# wpa_cli -ieth1 scan //搜索无线网
bash# wpa_cli -ieth1 scan_results //显示搜索结果
bash# wpa_cli -ieth1 add_network
bash# iwconfig eth1 essid "you_wifi_net"
bash# wpa_cli -ieth1 password 0 "password"
bash# wpa_cli -ieth1 enable_network



###19th,Jul
修改vi frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
把tiwlan0改eth1
暂时未编译

###开始没有选择第二步的debug选项,选上,在external/wpa_supplicant目录下有mm编译
得到
system/bin/wpa_cli---vvv1
system/lib/libwpa_client.so---vvv1
system/bin/wpa_supplicant---vvv1
###试一下android private socket
修改vi system/etc/wifi/wpa_supplicant.conf
vi data/misc/wifi/wpa_supplicant.conf
修改init.rc
在chmod那里把unix socket的那段注释
在启动wpa_supplicant的时候增加
socket wpa_eth1 dgram 660 wifi wifi

结果还是不行

###只好在external/wpa_supplicant/wpa_ctrl.c中添加
LOGW,注意得先加入头文件和LOG_TAG
 17 #define LOG_TAG "WifiQiu"
 18 #include "cutils/log.h"
mm编译得到
system/bin/wpa_cli---vvv2
system/lib/libwpa_client.so---vvv2
但是竟然没有WifiQiu输出,不知道是不是没有用make而是mm的缘故

###20th,Jul
1.BoardConfig.mk增加了HAVE_CUSTOM_WIFI_DRIVER_2 := true
2.修改wifi/wifi.c中使得检查和卸载驱动的两个函数,用make编译得到
libhardware_legacy.so---v4
system/bin/wpa_cli---vvv2.1
system/bin/wpa_supplicant-v2
system/lib/libwpa_client.so---vvv2.1

###上面的版本还没有来的及测试,有发现问题
1.突然发现external/wpa_supplicant/wpa_ctrl.c中LOG不够全面,
一共有三种情况,漏了一个函数没有加,于是增加LOGW并使之可以区分
2.根据手动strace wpa_cli的提示
access("/data/misc/wifi/wpa_supplicant", F_OK) = -1 ENOENT (No such file or directory)
用grep 搜索到所在文件为external/wpa_supplicant/wpa_cli.c
把它修改为:/data/misc/wifi
用mm分别在external/wpa_supplicant和hardware/libhardware_legacy中编译
得到
system/bin/wpa_cli---vvvvv3
system/lib/libwpa_client.so---vvv3
libhardware_legacy.so---v5

启动之后发现是在对socket进行连接的时候出错了
connect(ctrl->s, (struct sockaddr *) &ctrl->dest,sizeof(ctrl->dest)) < 0)
而且不能关闭wifi
只好重新修改wifi.c直接在unload函数中返回0,使得wifi能被关闭
libhardware_legacy.so---v5.1

###21th,Jul使用private的时候再次手动调试
# wpa_supplicant -dd -Dwext -ieth1 -c /system/etc/wifi/wpa_supplicant.conf&
# ioctl[SIOCSIWPMKSA]: Invalid argument
mkdir[ctrl_interface]: Permission denied

[1] + Done(255)                  wpa_supplicant -dd -Dwext -ieth1 -c /system/etc/wifi/wpa_supplicant.conf
查找mkdir发现是在ctrl_iface_unix.c中
错误是出现在#ifdef ANDROID之外阿,诡异


###用donut中external/wpa_supplicant下的driver_wext.c替换地掉eclair中的
mm重新编译,得到:
wpa_supplicant---vvv3
$$$还是不行

###22th,Jul
把donut的wpa_supplicant文件夹拷贝到eclair下
用mm编译得到
system/bin/wpa_cli---vvvvv4
system/bin/wpa_supplicant---vvv4
system/lib/libwpa_client.so---vvv4
wpa_supplicant---vvv3
终于可以搜索到网络了,泪奔
但是,不能获取到ip地址呵呵

logcat提示:
I/WifiStateTracker(  713): DhcpHandler: DHCP request failed: Timed out waiting for DHCP to finish

###手动启动dhcp提示
eth1: open `/data/misc/dhcp/dhcpcd-eth1.pid': No such file or directory
在init.rc中增加
mkdir /data/misc/dhcp 0777 wifi wifi
chmod 0777 /data/misc/dhcp
chown wifi wifi /data/misc/dhcp
还是不能获得地址
eth1: flock `/data/misc/dhcp/dhcpcd-eth1.pid': Try again
后来把上面的wifi 改为dhcp,还是不能获得IP地址

$$
把dhcpcd杀了,手动启动
# dhcpcd -f /system/etc/dhcpcd/dhcpcd.conf -d eth1
eth1: dhcpcd 4.0.1 starting
eth1: hardware address = 00:1a:6b:a2:38:65
eth1: executing `/system/etc/dhcpcd/dhcpcd-run-hooks', reason PREINIT
eth1: /system/etc/dhcpcd/dhcpcd-run-hooks: Permission denied
eth1: waiting for carrier
eth1: host does not support a monotonic clock - timing can skew
eth1: timed out
eth1: executing `/system/etc/dhcpcd/dhcpcd-run-hooks', reason FAIL
eth1: /system/etc/dhcpcd/dhcpcd-run-hooks: Permission denied

$$把权限都改为777,再次执行
# dhcpcd -f /system/etc/dhcpcd/dhcpcd.conf -d eth1
eth1: dhcpcd 4.0.1 starting
eth1: hardware address = 00:1a:6b:a2:38:65
eth1: executing `/system/etc/dhcpcd/dhcpcd-run-hooks', reason PREINIT
eth1: waiting for carrier
eth1: host does not support a monotonic clock - timing can skew
eth1: timed out
eth1: executing `/system/etc/dhcpcd/dhcpcd-run-hooks', reason FAIL

$$还没有关闭android机呢,重新打开wifi,嘿嘿,能分配到地址了

但是...但是,还是不能上网,估计是由于地址的原因吧

把eth0禁用之后就可以上网了,呵呵

wifi移植告一段落

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