s5pc100 board android2.1环境下的RT3070 usb wifi移植

 

              S5PC100-board android 2.1  RT3070 usb wifi 移植

 

 

硬件环境:s5pc100开发板,rt3070usbwifi模块

软件环境:

unbuntu8.10;

linux-2.6.29内核

utc100_android_2.1源码;

rt3070模块驱动;

 

1.首先我们将需要的上述四个工作文件拷贝到工作目录下

 

 

2.接着我们查看一下linux-2.6.29-sansung

打开这个内核源码工作目录

查看一下里面的参数有没有设置正确

make menuconfig

 

(1)Networking support

                     ->wireless

                                   ->[*]Common routines for IEEE802.11 drivers

 

这个是关系到  wifi  相应服务的一些参数

打开后发现没有什么需要修改的

Device Drivers->

              ->Network device support

               ->[*]Wireless LAN

    [*] Wireless LAN (pre-802.11)                                   

   < >   STRIP (Metricom starmode radio IP)                        

    [*] Wireless LAN (IEEE 802.11)                                  

   <M>   Marvell 8xxx Libertas WLAN driver support                 

   < >     Marvell Libertas 8388 USB 802.11b/g cards               

[*]     Enable full debugging output in the Libertas module.    

   < >   USB ZD1201 based Wireless device support                  

< >   Wireless RNDIS USB support                                

   < > IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)     

 

 

这里也没有什么需要修改 的

 

3.由于我们默认的是像素是800x768,而我们的触屏像素默认的是480x272

所以要进行修改

Device Driversà

                            Graphics support à

                                          Support for frame buffer devices à

                                                 Select LCD Type (Innolux 4.3 inch(480x272))

                                                        (X) Innolux 4.3 inch (480x272)

修改 后我们回到linux-2.6.29-sansung下

make

会生成  zImage  这个就是真正的内核镜像文件 ,我们将其拷贝到tftpboot目录下


4. 接着我们对wifi模块相关的目录进行修改

将rt3070解压后在其目录下会找到三个工作目录

MODULE  

NETIF

UTIL

 

这三个目录分别是我们包含了我们需要使用的三个wifi加载模块

由于我们所使用的内核是linux-2.6.29,

所以我们需要查看顶层目录下的Makefile 

 

  2 all:

  3         make -C UTIL/

  4         $(SHELL) cp_util.sh

  5         make -C MODULE/

  6         $(SHELL) cp_module.sh

  7         make -C NETIF/

  8

  9 clean:

 10         make -C UTIL/ clean

 11         make -C MODULE/ clean

 12         make -C NETIF/ clean

 

5.再到RT3070原目录下的各个目录下进行修改

 

~/rt3070/MODULE/

~/rt3070/ NETIF/

~/rt3070/ UTIL/

在这个三个目录下会找到相应的Makefile

我们要修改其编译的源码工作路径

将其修改为内核所在的绝对路径:

 

107 ifeq ($(PLATFORM),PC)

108 # Linux 2.6

109 LINUX_SRC = /home/linux-2.6.29-sansung

 

 

由于我们选择的 平台选项为PC  即  PLATFORM = PC

所以我们只需修改PC这个选项的工作路径。

 

6.进行修改后我们到回到~/rt3070/目录下

make

z在三个目录下会生成三个相应的.ko

注!:~/rt3070/MODULE$  这个目录下的

RT2870STA.dat   这个文件

这个文件非常重要,是RT3070的固件(firmware)内含它的一些配置属性。

 

接着我们到android_2.1目录下

7. 安装交叉工具链

下载cross-4.2.2-eabi.tar.bz2 和arm-none-linux-gnueabi-arm-2008q3-72-for-linux.tar.bz2

(网上查找)

 arm-none-linux-gnueabi-arm-2008q3-72-for-linux.tar.bz2

 cross-4.2.2-eabi.tar.bz2

 将这两个解压缩文件安装到/usr/local/arm/下

然后使用tar 命令解压这两个文件

这两个工具链要安装到/usr/local/arm/下 。

执行命令:

 $ tar xvf arm-none-linux-gnueabi-arm-2008q3-72-for-linux.tar.bz2

 接下来将cross-4.2.2-eabi.tar.bz2解压

 $ tar xvf  cross-4.2.2-eabi.tar.bz2


8.之后回到android2.1_v1.

先编译android 源码   make TARGET_PRODUCT=s5p100

编译需要很长时间,编译完之后我们制作filesystem(文件系统),

在根目录下编写一个制作文件系统的shell脚本;

vim make_utc100_yaffs2_image.sh

 

#!/bin/sh

rm ./filesystem -rf

mkdir ./filesystem

 cp ./out/target/product/utc100/root/* ./filesystem/ -a

 cp ./out/target/product/utc100/system ./filesystem/ -a

 cp ./vendor/sec/utc100/app/* ./filesystem/system/app/ -a

tar zxvf ./vendor/sec/utc100/busybox.tgz -C ./filesystem/system/

#./mkyaffs2image ./utc100_root/ utc100_root.img

 

 做完这步之后修改这个脚本的执行权限  chmod 755 make_utc100_yaffs2_image.sh

这样我们就能够执行  ./ make_utc100_yaffs2_image.sh

 

接着我们就能够在当前目录下找到 filesystem 这个目录下 了

当然你也可以通过拷贝来制作文件系统:

在主目录下mkdir filesystem

cd utc100_android_2.1

 cp ./out/target/product/utc100/root/* ./filesystem/ -a

 cp ./out/target/product/utc100/system ./filesystem/ -a

 cp ./vendor/sec/utc100/app/* ./filesystem/system/app/ -a


使用这几步后,一个文件系统就这样制作成功了

 文件系统制作以后

需要改变其用户所有组

  sudo chown filesystem/* root.root

sudo chmod 777 filesystem/*

然后我们将 filesystem拷贝至   /opt/目录下 

 

到根目录下修改 sudo vim /etc/exports

 最后一行进行添加:/opt/filesystem  *(rw,sync,no_subtree_check,no_root_squash)

# /etc/exports: the access control list for filesystems which may be exported

#               to NFS clients.  See exports(5).

#

# Example for NFSv2 and NFSv3:

# /srv/homes       hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)

#

# Example for NFSv4:

# /srv/nfs4        gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)

# /srv/nfs4/homes  gss/krb5i(rw,sync,no_subtree_check)

#

/opt/filesystem  *(rw,sync,no_subtree_check,no_root_squash)


9.接下来我们通过网络挂载启动开发板,做好相应的开发板环境配置

 

setenv gatewayip 192.168.1.1

setenv ipaddr    192.168.1.175    //开发板IP

setenv serverip  192.168.1.155   //VMWARE IP

setenv bootcmd tftp 20008000 zImage\;bootm 20008000

setenv bootargs root=nfs nfsroot=192.168.1.155:/opt/filesystem init=/linuxrc console=ttySAC0,115200 ip=192.168.1.175

 

如果我们使用了minicom,

我们在开启开发板的时候要将VM虚拟机的窗口Removeabled Deivces-à  serial port设置 成 disconnect,


10.启动开发板后发现,s5pc100 板子启动时提示没办法mount上nfs?

       解决办法:

(1)    修改init.rc中注释掉69 行 72行 102行(这几行主要意思就是mount yaffs的文件系统)而我们已经自己制作了文件系统。

修改保存之后

重新启动

问题又出现了,提示:s5pc100 板子启动时没办法进入bin /sh ?

       解决办法:

       (1)修改init.rc中注释掉console /system/busybox/bin/ash

  将 console /system/bin/sh前面的#号去掉

接着我们的开发板就能够正常启动到开发板了     

11.但是我们按触摸屏时发现X方向是反的,

       解决办法:触摸屏驱动ts是一个典型的input子系统的设备,上报的x值有问题,导致屏幕的位置不正确,所以要修改上报input子系统的x方向的值。

       1.首先打开~/linux-2.6.29-sansung/drivers/input/touchscreen/s3c-ts.c 打开相关调试信息

       2.点击屏幕最左和最右两个点,在串口中发现根据adc转换后的这两个点的x值和大约为800,说明整个屏的在x方向总共分了800个位置

       3.因为屏幕x方向是触摸方向是反的,对故在191行增加一句ts->xp = 800 -ts->xp;在上报input子系统前修改x值。

修改这个以后重新在~/linux-2.6.29-sansung/目录下make

重新编译加载内核,然后将其拷贝替换之前的zImage

 

12.重新启动开发板,将USBWIFI模块插在开发板上,在触摸屏上打开menu,点击settings中的Wireless & networks按下Wi-Fi按钮

它就会自动调用WifiEnabler.java

在串口终端输入:logcat &   打印后台信息

提示:unable to start wi-fi

修改HAL层的hardware/libhardware_legacy/wifi/wifi.c

wifi.c 是 wifi 的hardware 抽像层,必须修改 wifi_load() . wifi_unload()这两个加载和卸载的结构体

修改

int wifi_load_driver()

181 {

182     char driver_status[PROPERTY_VALUE_MAX];

183     int count = 100; /* wait at most 20 seconds for completion */

184     LOGE("starting load wifi driver!");

185     if (check_driver_loaded()) {

186         return 0;

187     }

188        

189         /*

190     if (insmod(DRIVER_MODULE_PATH_1, DRIVER_MODULE_ARG) < 0)

191         {

192                 LOGE("%s , wifi insmod module1  failed!",__FUNCTION__);

193                 return -1;

194         }

195

196     if (insmod(DRIVER_MODULE_PATH_2, DRIVER_MODULE_ARG) < 0)

197         {

198                 LOGE("%s , wifi insmod module2  failed!",__FUNCTION__);

199                 return -1;

200         }

 

202

203     if (insmod(DRIVER_MODULE_PATH_3, DRIVER_MODULE_ARG) < 0)

204         {

205                 LOGE("%s , wifi insmod module3  failed!",__FUNCTION__);

206                 return -1;

207         }

208         

209         LOGE("starting wait 10s");

210         usleep(10000000);

211         LOGE("end waiting 10s");

212         */

 

 

 

 

 

int wifi_unload_driver()

238 {

239     int count = 20; /* wait at most 20 seconds for completion */

240            /*

241          if (rmmod(DRIVER_MODULE_NAME_1) == 0)

242         {      

243                 LOGE("unload drvier1 successfull!\n");

244                 usleep(500000);

245                 if(rmmod(DRIVER_MODULE_NAME_2) == 0)

246                 {

247                         usleep(500000);//wait for a second

248                         LOGE("unload drvier2 successfull!\n");

249                         if(rmmod(DRIVER_MODULE_NAME_3) == 0)

250                         {

251                                 LOGE("unload drvier3 successfull!\n");

252                                 return 0;

253                         }

254                         else

255                         {

256                                 LOGE("unload drvier3 failed!\n");

257                                 return -1;

258                         }

                }

260                 else

261                 {

262                         LOGE("unload drvier2 failed!\n");

263                         return -1;

264                 }

265          }

266          else

267          {

268                 LOGE("unload drvier1 failed!\n");

269                 return -1;

270

271          }*/

272

273            return 0;

274

275         /*

276                 while (count-- > 0)

277                 {

                     if (!check_driver_loaded())

279                         break;

280                     usleep(500000);

281                 }

282                

283                 if (count)

284                 {

285                     return 0;

286                 }

287                

288                 return -1;

289         }

290         else

291         return -1;*/

292 }

 

对这些行进行修改

还要修改

WIFI_DRIVER_MODULE_PATH等相关宏指定的名称和路径,保证顺利加载驱动和firmware

把所需要的wifi模块加进来

54 #ifndef WIFI_DRIVER_MODULE_PATH

 55 #define WIFI_DRIVER_MODULE_PATH_1         "/system/lib/modules/rtutil3070sta.ko"

 56 #define WIFI_DRIVER_MODULE_PATH_2         "/system/lib/modules/rt3070sta.ko"

 57 #define WIFI_DRIVER_MODULE_PATH_3         "/system/lib/modules/rtnet3070sta.ko"

 

 

 

61 #define WIFI_DRIVER_MODULE_NAME_1         "rtnet3070sta"

 62 #define WIFI_DRIVER_MODULE_NAME_2         "rt3070sta"

 63 #define WIFI_DRIVER_MODULE_NAME_3         "rtutil3070sta"

 

 

 

69 #define WIFI_FIRMWARE_LOADER            ""

 70 #endif

 71 #define WIFI_TEST_INTERFACE             "ra0"

 72

 73 static const char IFACE_DIR[]           = "/data/misc/wifi/wpa_supplicant";

 74 //static const char IFACE_DIR[]           = "/data/system/wpa_supplicant";

 75 static const char DRIVER_MODULE_NAME_1[]  = WIFI_DRIVER_MODULE_NAME_1;

 76 static const char DRIVER_MODULE_NAME_2[]  = WIFI_DRIVER_MODULE_NAME_2;

 77 static const char DRIVER_MODULE_NAME_3[] = WIFI_DRIVER_MODULE_NAME_3;

 78 static const char DRIVER_MODULE_TAG[]   = WIFI_DRIVER_MODULE_NAME_1 " ";

 79 static const char DRIVER_MODULE_PATH_1[]  = WIFI_DRIVER_MODULE_PATH_1;

 80 static const char DRIVER_MODULE_PATH_2[]  = WIFI_DRIVER_MODULE_PATH_2;

 81 static const char DRIVER_MODULE_PATH_3[]  = WIFI_DRIVER_MODULE_PATH_3;

 

 

82 static const char DRIVER_MODULE_ARG[]   = WIFI_DRIVER_MODULE_ARG;

 83 static const char FIRMWARE_LOADER[]     = WIFI_FIRMWARE_LOADER;

 84 static const char DRIVER_PROP_NAME[]    = "wlan.driver.status";

 85 static const char SUPPLICANT_NAME[]     = "wpa_supplicant";

 86 static const char SUPP_PROP_NAME[]      = "init.svc.wpa_supplicant";

 87 static const char SUPP_CONFIG_TEMPLATE[]= "/system/etc/wifi/wpa_supplicant.conf";

 88 static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";

 89 static const char MODULE_FILE[]         = "/proc/modules";

 

 

 

 

修改完wifi.c之后

我们打开开发板接着调试

       又出现了问题

       提示

 

E/WifiHW  ( 1893): Cannot open "/system/etc/wifi/wpa_supplicant.conf

              usbcore: deregistering interface driver rt2870

              <--- rtusb exit onf": No such file or directory

 

这主要是相关的wpa_supplicant的配置没做

 修改init.rc

 

           #for wifi

           mkdir /system/etc/wifi 0777 wifi 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

            mkdir /data/misc/wifi 0777 wifi wifi

            mkdir /data/misc/wifi/sockets 0777 system wifi

            mkdir /data/misc/wifi/wpa_supplicant 0777 wifi wifi

        

            mkdir /data/system/wpa_supplicant

            chown system wifi /data/system/wpa_supplicant

            chmod 0777 /data/system/wpa_supplicant

        //添加DHCP功能

            mkdir /data/misc/dhcp

            chmod 0777 /data/misc/dhcp

            chown dhcp dhcp /data/misc/dhcp

 

            setprop wifi.interface ra0

 

 

 

              在init.rc的service启动部分添加如下:

              #这里wpa_supplicant 使用wireless extension 作为 driver, wlan0 为intercace, /data/misc/wifi/wpa_supplicant.conf

             #作为配置文件

               service wpa_supplicant /system/bin/wpa_supplicant -d -Dwext -ira0 -c/data/misc/wifi/wpa_supplicant.conf

             #user system

             group system wifi inet

             disabled

             oneshot

 

               service dhcpcd /system/bin/dhcpcd -f /system/etc/dhcpcd/dhcpcd.conf -d ra0

             group system dhcp wifi

             disabled

             oneshot

 

 

       13.启动时出现以下提示,原因是init.rc中启动service那几行的位置不正确

                            init: /init.rc: 108: invalid option 'chown'

                            init: /init.rc: 108: invalid option 'chmod'

                            init: /init.rc: 108: invalid option 'chown'

                            init: /init.rc: 108: invalid option 'chmod'

                            将关于启动service的命令放到init.rc的末尾。

 

 

 

             

       14.再次测试遇到以下问题:E/logwrapper( 2069): executing /system/bin/wpa_supplicant failed: No such file or directory

                    粗略看了一下external/wpa_supplicant下的Android.mk发现里面

                     WPA_BUILD_SUPPLICANT := false 修改成true(它本来要满足一些条件才能变成true的,这里直接改了先。)

                     改了之后在上级目录执行mm指令

                     就产生了相关的system/bin/wpa_supplicant

                     将产生的bin文件和.so文件拷贝到文件系统中去。

      

                           

        15.再次测试遇到以下问题: Open file "/etc/Wireless/RT2870STA/RT2870STA.dat" failed!             

                     将rt3070 源码Module文件夹下的固件RT2870STA.dat放置到Android文件系统下

                       system/etc/Wireless/RT2870STA目录下,没有的目录要自己建立。

                

         16.再次测试遇到以下问题:Error changing group ownership of /data/misc/wifi/wpa_supplicant.conf

                

                   在wifi.c中找到

                   static const char SUPP_CONFIG_FILE[]    = "/data/misc/wifi/wpa_supplicant.conf";

                   destfd = open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660);

                   说明文件wpa_supplicant.conf是wifi.c中创建的,权限为system system。

                  

                   但是wifi.c中又有这样的语句

                    if (chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0) {

                             LOGE("Error changing group ownership of %s to %d: %s",

                         SUPP_CONFIG_FILE, AID_WIFI, strerror(errno));

                             unlink(SUPP_CONFIG_FILE);

                             return -1;

                                }

                    意思要转变/data/misc/wifi/wpa_supplicant.conf这个文件组权限为wifi,明显在这是行不通的。

                     因为wifi.c本身的权限只有system system,除非wifi.c拥有root权限。

                    

                     解决办法:

                     注释掉(chown(SUPP_CONFIG_FILE, AID_SYSTEM, AID_WIFI) < 0这段句话,不要在代码中改它的权限。

                     在这段代码前面加上

                      chmod(SUPP_CONFIG_FILE, 0777);                      这样的话不管是谁都可以读取这个config文件。                

      17.提示Unable to open connection to supplicant on "/data/system/wpa_supplicant/sta": No suchfile or directory      

               

                     原因打开的路径的不对,在wpa_supplicant.conf中设定的路径为

                     ctrl_interface=DIR=/data/misc/wifi/wpa_supplicant

                     但是在wifi.c中设定的static const char IFACE_DIR[]不正确,所以在建立socket时失败。

                     修改wifi.c中的两个宏

                     #define WIFI_TEST_INTERFACE       "ra0"

                     static const char IFACE_DIR[]           = "/data/misc/wifi/wpa_supplicant";

 

      18.wifi_connect_to_supplicant函数无法执行成功,返回值为-1,打印相关信息发现函数体内

                            wpa_ctrl_attach(monitor_conn)无法正确执行。

                            分析wpa_ctrl_attach函数:

                                          ->wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6, buf, &len, NULL);//socket的建立和地址绑定是在wpa_ctrl_open(ifname)中完成

                                                        ->(send(ctrl->s, _cmd, _cmd_len, 0) < 0)//发送命令,这个命令发送后将由wpa_supplicant的守护进程

                                                        ->res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);//select 等带回应(10s 后超时)

                                                        ............................

                            wpa_supplicant 接收消息是在以下函数中完成的:

                            wpa_supplicant_ctrl_iface_receive       函数( ctrl_iface_unix.c  )

                                          ->recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &fromlen);//接收消息

                                          ->if (os_strcmp(buf, "ATTACH") == 0) //收到消息并判断

                                                 ->wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen)//执行对应的处理函数

                                                 ->if (reply_len == 2)

                                                 ->sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, fromlen);//返回OK给HAL层(wpa_ctrl_request)

                            问题出现了,明明这里发送OK,但是select函数并没有接收到,后打印sendto的异常代码,发现是

                            permission Deny,又是权限的问题。打印from,发现路径为data/misc/wifi/sockets

                            解决办法:

                            修改wpa_ctrl.c中的wpa_ctrl_open函数

                            chmod(ctrl->local.sun_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);//这里的local.sun_path就是路径data/misc/wifi/sockets

                            修改为

                            chmod(ctrl->local.sun_path, 0777);

                           

        19. D/wpa_supplicant( 2096): No suitable AP found.

                                          没有搜索到的网络列表

                                         

                                          修改config_file.c中:

                                          wpa_config_read(const char *name)函数

                                          chmod(name, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);

                                          修改为

                                          chmod(name, 0777);

 

 

     20.能够进行AP scan但是搜索到之后wifi睡眠,当你再次触摸屏幕的时候系统崩溃

                             原因:代码中没有实现相关的唤醒的函数,所以当你再次触摸屏幕的时候系统崩溃。

                        关闭wifi的睡眠功能:

                        在wifisettings里面按下menu键,然后点击advance选项,然后在弹出的对话框中选择

                        wifi_sleep_options,最后选择never(这样wifi的部分就不会睡眠了)

                     

 

   21. /s5pc100/android2.1/frameworks/base/wifi/java/android/net/wifi 路径

                 WifiStateTracker.java:353:        mInterfaceName = SystemProperties.get("wifi.interface", "eth0");

                 修改为

                  WifiStateTracker.java:353:        mInterfaceName = SystemProperties.get("wifi.interface", "ra0");

      

     22.如何自动获得IP?使用dhcp

                            修改源码目录下external/dhcpcd下的android.mk文件

                            取消注释

                             26  include $(CLEAR_VARS)

                             27 LOCAL_MODULE := dhcpcd.conf

                             28 LOCAL_MODULE_TAGS := user

                             29 LOCAL_MODULE_CLASS := ETC

                             30 LOCAL_MODULE_PATH := $(etc_dir)

                             31 LOCAL_SRC_FILES := android.conf

                             32 include $(BUILD_PREBUILT)

                             

                            然后重新编译mm

                            将编译产生的dhcpcd.conf放置到文件系统的目录system/etc/dhcpcd/dhcpcd.conf

                           

                            确保init.rc中有如下的语句启动dhcp

                            mkdir /data/misc/dhcp 0770 dhcp dhcp

                            chown dhcp dhcp /data/misc/dhcp

                           

                            service dhcpcd /system/bin/dhcpcd -f /system/etc/dhcpcd/dhcpcd.conf -d eth0

                               group system dhcp

                               disabled

                               oneshot

  23.经过这些步骤,终于能够在开发板上利用WIFI模块上网了,android的logcat果然是个神器啊!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Keep Coding...

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值