一、开发环境
开发板Linux内核版本:2.6.35
无线网卡型号:RTL8188ETV
RTL8188驱动版本:rtl8188EUS_rtl8189ES_linux_v4.1.2_4787.20120803.tar.gz
二、内核配置
进入内核源码根目录:
make menuconfig
网络配置:增加802.11协议栈的支持
Networking support
Wireless
无线网卡配置
Device Drivers
Network device support
Wireless LAN
USB网卡配置
Device Drivers
USB support
注意:配置完成后,必须编译一次,因为后面的网卡驱动需要用到内核里部分.o文件,我这里是执行make uImage 编译内核。
三、无线网卡驱动编译
解压并进入驱动源码根目录:
修改MakeFile
vim MakeFile
配置
CONFIG_RTL8188E = y
CONFIG_USB_HCI = y
CONFIG_POWER_SAVING = n
接下来需要增加一个平台信息,名字随便,内容主要包括指定编译器、内核源码目录:
CONFIG_PLATFORM_IMX283 = y
ifeq ($(CONFIG_PLATFORM_IMX283), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH :=arm
CROSS_COMPILE :=arm-fsl-linux-gnueabi-
KVER :=2.6.35.3
KSRC :=/ZLG_linux/linux-2.6.35.3
endif
注意:内核版本必须和开发板上运行的Linux版本一致,否则加载驱动会提示Unknown symbol skb_put (err -22)等错误,该错误说明内核版本和实际不一致!!!
然后执行make,编译完成后会生成8188eu.ko文件,接着在开发板上加载8188eu.ko
这样驱动就是加载成功了,并且成功识别了无线网卡。
查看所有网卡:
ifconfig -a
启动无线网卡
ifconfig wlan0 up
ifconfig
可以看到已经出现一个名为wlan0的无线网卡,但是要使用该网卡还需要wireless tools 工具。
四、wireless tools 工具移植
wireless tools 是操作 WIFI 的工具集合,包括一下工具:
- iwconfig:设置无线网络相关参数。
- iwlist:扫描当前无线网络信息,获取 WIFI 热点。
- iwspy:获取每个节点链接的质量。
- iwpriv:操作 WirelessExtensions 特定驱动。
- ifrename:基于各种静态标准命名接口。
wireless tools源码下载:wireless tools
wireless tools 工具只能连接开放或者WEP加密的AP,但是现在大多数WIFI都是WPA加密的,如果要连接这些WPA加密的WIFI,需要使用其他的工具(wpa_supplicant),这个后面会介绍。
解压并进入wireless tools源码根目录:
修改MakeFile
vim MakeFile
指定交叉编译器
CC = arm-fsl-linux-gnueabi-gcc
AR = arm-fsl-linux-gnueabi-ar
RANLIB =arm-fsl-linux-gnueabi-ranlib
编译
make
编译完成以后就会在当前目录下生成 iwlist、iwconfig、iwspy、iwpriv、ifrename 这 5 个工具,另外还有很重要的 libiw.so.29 这个库文件。将这 5 个工具拷贝到开发板根文件系统下的/usr/bin 目录中,将 libiw.so.29 这个库文件拷贝到开发板根文件系统下的/usr/lib 目录中。
iwlist wlan0 scan //扫描wifi
iwconfig wlan0 essid “oppo” //连接热点"oppo"
udhcpc –i wlan0 //动态获取ip -i指定网卡
有时候,当利用 udhcpc –i wlan0获取到ip之后,再次执行ifconfig可能会发现wlan0的ip依旧是空白,这是因为udhcpc只是请求一个ip可用的ip地址,但是这个地址并没有被写入到网卡设备中去,我们还需要一个配置文件来将申请到的ip地址写入设备。
配置文件如下:
#!/bin/sh
# udhcpc script edited by Tim Riker <[email protected]>
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
RESOLV_CONF="/etc/resolv.conf"
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"
case "$1" in
deconfig)
/sbin/ifconfig $interface 0.0.0.0
;;
renew|bound)
/sbin/ifconfig $interface $ip $BROADCAST $NETMASK
if [ -n "$router" ] ; then
echo "Deleting routers"
while route del default gw 0.0.0.0 dev $interface 2>/dev/null ; do
:
done
for i in $router ; do
route add default gw $i dev $interface
done
fi
echo -n > $RESOLV_CONF
[ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
for i in $dns ; do
echo adding dns $i
echo nameserver $i >> $RESOLV_CONF
done
;;
esac
exit 0
将该文件命名为default.script,放在/usr/share/udhcpc目录下即可。
五、调试过程中遇到的问题
1. insmod 之后没有打印调试信息,仅仅打印了添加新驱动成功的信息。
原因之一可能是无线网卡没有插上,若已经插上了无线网卡,可以先通过lsusb指令查看是否已经挂载无线网卡设备,lsusb会展示所有已经挂载的USB设备的VID和PID,我的网卡VID=0x0BDA,PID=0x0179。接着打开驱动源码的usb_intf.c文件(我的网卡是usb接口,其他接口请找对应的文件),查找rtw_usb_id_tbl数组中定义的USB设备是否包含上面的VID和PID。我的usb_intf.c文件就没有定义网卡设备:
#ifdef CONFIG_RTL8188E
/*=== Realtek demoboard ===*/
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)},//Default ID
#endif
可以看到此处的USB设备的PID并不是我们在使用的设备的PID,这个驱动程序是为PID=0x8179的设备服务的,但是我们系统里没有这个设备,我们这里直接把0x8179改成我们设备的PID=0x0179,然后重新编译并加载驱动。
此时,应该会打印调试信息了。
2. Unknown symbol wireless_send_event 、disagrees about version of symbol wireless_send_event等错误信息
驱动MakeFile中内核版本要和实际版本一致 比如2.6.35.3
3. /rtl8188EUS/os_dep/linux/os_intfs.c:960: error: ‘struct net_device’ has no member named 'wireless_handlers’
Wireless LAN 目录里IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)都选择上目的是打开CONFIG_WIRELESS_EXT=y CONFIG_WEXT_PRIV=y
#ifdef CONFIG_WIRELESS_EXT
/* List of functions to handle Wireless Extensions (instead of ioctl).
* See <net/iw_handler.h> for details. Jean II */
const struct iw_handler_def * wireless_handlers;
/* Instance data managed by the core of Wireless Extensions. */
struct iw_public_data * wireless_data;
#endif
参考博客/文章:
- 【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
- linux下udhcpc的使用
- RTL8188ETV驱动移植