楼主有一块卡皇 USB 网卡,Realtek 8187L 系列,09 年购入,现在依旧在服役。虽然这款无线网卡的驱动已经内置到内核里了,但是却有不少的毛病,比如信号不好,有掉线的情况发生,于是我想我几年前也编译过这个驱动,索性编译一个好了,没想到这却是折腾的开始。。。好了,题外话少说,现在进入正题
在 Realtek 的官方网站上有 8187 系列的 Linux 版本驱动下载,是 2012 年更新的版本,支持 3.0~3.2 的内核。但是内核更新了这么久,官方的驱动是否还能使用?在我的 openSUSE 13.1 下进行编译,情况如下
make[1]: Entering directory `/usr/src/linux-3.11.10-17-obj/x86_64/desktop'
CC [M] /home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.o
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:153:22: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘rtl8187_usb_probe’
static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:155:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘rtl8187_usb_disconnect’
static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf);
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:168:12: error: ‘rtl8187_usb_probe’ undeclared here (not in a function)
.probe = rtl8187_usb_probe,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:169:16: error: ‘rtl8187_usb_disconnect’ undeclared here (not in a function)
.disconnect = rtl8187_usb_disconnect,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c: In function ‘rtl8180_proc_module_init’:
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:427:2: error: implicit declaration of function ‘create_proc_entry’ -Werror=implicit-function-declaration]
rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:427:14: warning: assignment makes pointer from integer without a cast [enabled by default]
rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c: In function ‘rtl8180_proc_init_one’:
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:461:16: warning: assignment makes pointer from integer without a cast [enabled by default]
priv->dir_dev = create_proc_entry(dev->name,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:479:2: error: implicit declaration of function ‘create_proc_read_entry’ -Werror=implicit-function-declaration]
e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:479:4: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:489:4: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:518:4: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c: In function ‘rtl8180_tx’:
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:1382:12: warning: cast from pointer to integer of different size -Wpointer-to-int-cast]
u8 seg = ((u32)txbuf % 4);
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c: In function ‘rtl8187_usb_initendpoints’:
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:1588:14: warning: cast from pointer to integer of different size -Wpointer-to-int-cast]
seg_size = (u32)ptrcontext->transfer_buffer % 4;
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c: At top level:
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:3762:22: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘rtl8187_usb_probe’
static int __devinit rtl8187_usb_probe(struct usb_interface *intf,
^
/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.c:3862:23: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘rtl8187_usb_disconnect’
static void __devexit rtl8187_usb_disconnect(struct usb_interface *intf)
^
cc1: some warnings being treated as errors
make[4]: *** [/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187/r8187_core.o] Error 1
make[3]: *** [_module_/home/cheng/rtl8187L_linux_1041.0209.2012/rtl8187] Error 2
make[2]: *** [sub-make] Error 2
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/src/linux-3.11.10-17-obj/x86_64/desktop'
make: *** [all] Error 2
官方的驱动早已不能编译成功。怎么破?
虽然我是小白,看不懂编译是什么错误,不过有 Google 嘛。于是上网搜索了一下,发现在 Ubuntu 论坛上有人提出了解决方案 ubuntuforums.org/showthread.php?p=12775665#post12775665 在"r8187.h" 文件的开头加入
#ifndef __devinit
#define __devinit
#define __devexit
#endif
更改之后满怀信心再次编译,可还是错误:
make[1]: Entering directory `/usr/src/linux-3.11.10-17-obj/x86_64/desktop'
CC [M] /home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.o
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c: In function ‘rtl8180_proc_module_init’:
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:427:5: error: implicit declaration of function ‘create_proc_entry’ -Werror=implicit-function-declaration]
rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:427:17: warning: assignment makes pointer from integer without a cast [enabled by default]
rtl8180_proc=create_proc_entry(RTL8187_MODULE_NAME, S_IFDIR, init_net.proc_net);
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c: In function ‘rtl8180_proc_init_one’:
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:461:19: warning: assignment makes pointer from integer without a cast [enabled by default]
priv->dir_dev = create_proc_entry(dev->name,
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:479:5: error: implicit declaration of function ‘create_proc_read_entry’ -Werror=implicit-function-declaration]
e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:479:7: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:489:7: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:518:7: warning: assignment makes pointer from integer without a cast [enabled by default]
e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c: In function ‘rtl8180_tx’:
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:1382:15: warning: cast from pointer to integer of different size -Wpointer-to-int-cast]
u8 seg = ((u32)txbuf % 4);
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c: In function ‘rtl8187_usb_initendpoints’:
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.c:1588:20: warning: cast from pointer to integer of different size -Wpointer-to-int-cast]
seg_size = (u32)ptrcontext->transfer_buffer % 4;
^
cc1: some warnings being treated as errors
make[4]: *** [/home/cheng/rtl8187-Linux-Driver-master/rtl8187/r8187_core.o] Error 1
make[3]: *** [_module_/home/cheng/rtl8187-Linux-Driver-master/rtl8187] Error 2
make[2]: *** [sub-make] Error 2
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/src/linux-3.11.10-17-obj/x86_64/desktop'
make: *** [all] Error 2
这回我发现是由于没有申明 create_proc_entry 这个函数,去 Google 一搜发现在 3.10 内核之后将 create_proc_entry 去除了,改为 proc_create 函数了。于是我将函数一一进行更改,改完之后编译还是出错,这次是什么错误呢
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/../ieee80211/ieee80211_module.c:320:6: error: dereferencing pointer to incomplete type
e->read_proc = show_debug_level;
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/../ieee80211/ieee80211_module.c:321:6: error: dereferencing pointer to incomplete type
e->write_proc = store_debug_level;
^
/home/cheng/rtl8187-Linux-Driver-master/rtl8187/../ieee80211/ieee80211_module.c:322:6: error: dereferencing pointer to incomplete type
e->data = NULL;
^
make[4]: *** [/home/cheng/rtl8187-Linux-Driver-master/rtl8187/../ieee80211/ieee80211_module.o] Error 1
make[3]: *** [_module_/home/cheng/rtl8187-Linux-Driver-master/rtl8187] Error 2
make[2]: *** [sub-make] Error 2
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/src/linux-3.11.10-17-obj/x86_64/desktop'
make: *** [all] Error 2
事情到这里我彻底没有办法了。。由于我对系统编程知之甚少,而且对硬件驱动完全不知,实在是没有办法再改动源代码了。在此向论坛的各位大牛求助,能否帮忙一起将此驱动在 3.10 版本内核和之后的版本中编译通过。先行谢过各位!