Linux添加WIFI驱动

文章目录

      • 编译libnl
      • 编译openssl
      • 编译wpa_supplicant
      • 编译Wireless Tools
      • 安装wifi相关工具
      • 编译RTL8188eu驱动

首先确定要添加支持wifi的芯片组,我要添加的为rtl8188eu。首先想到的是,看一下海思提供的文档里有没有相关WIFI的资料。还真找到了,路径为:随安保Hi3516E V200R001C01SPC010_ReleaseDoc\zh\02.only for reference\software\WiFi 使用指南.pdf,如图:
Linux添加WIFI驱动_第1张图片
先试一下海思提供的文件系是否支持wifi相关指令,输入iwconfig提示找不到。先编这些需要的工具吧,看到这海思的文档。
Linux添加WIFI驱动_第2张图片

编译libnl

先编译libnl库,下载地址:http://www.linuxfromscratch.org/blfs/view/svn/basicnet/libnl.html
版本为:libnl-3.5.0,先下载,然后解压。

./configure CC=arm-himix100-linux-gcc --host=arm-himix100-linux --enable-static --enable-shared LIBS=-lpthread --prefix=$(pwd)/_install

运行后,报错了。

checking for dlfcn.h... (cached) yes
checking for pthread_mutex_lock in -lpthread... yes
checking for strerror_l... no
configure: WARNING: bison not found. Please install before continuing.
configure: WARNING: flex not found. Please install before continuing.
configure: error: Required packages are missing. Please install them and rerun /configure
root@qddytt:/opt/IPC3516EV200/libnl-3.5.0# 

大意是,没有安装bison和flex。

apt-get install bison
apt-get install flex

然后再运行上面的提令,未再报错了。接下来,执行

make
make install

然后看了一下_install目录,如下:
Linux添加WIFI驱动_第3张图片

编译openssl

下载地址:https://www.openssl.org/source/old/1.0.2/openssl-1.0.2s.tar.gz

tar xzf openssl-1.0.2s.tar.gz
cd openssl-1.0.2s
./config no-asm -shared --prefix=$(pwd)/_install
gedit Makefile #将CC,AR,NM的宏加上arm-himix100-linux-
make
make install

编译wpa_supplicant

下载地址:http://w1.fi/wpa_supplicant/

我下载的是:wpa_supplicant-2.6.tar.gz 这个版本。

#这里是整理好的编译指令(下面的各种报错已通过这里的步骤处理了)
tar xzf wpa_supplicant-2.6.tar.gz
cd wpa_supplicant-2.6
cd wpa_supplicant/
cp defconfig .config
gedit Makefile #将里面的内容做如下修改:
CC=arm-linux-gnueabihf-gcc
gedit .config #将CFLAGS,LIBS改为如下:
CFLAGS += -I/opt/IPC3516EV200/openssl-1.0.2s/_install/include
LIBS += -L/opt/IPC3516EV200/openssl-1.0.2s/_install/lib
CFLAGS += -I/opt/IPC3516EV200/libnl-3.5.0/_install/include/libnl3
LIBS += -L/opt/IPC3516EV200/libnl-3.5.0/_install/lib
#再添加
CONFIG_LIBNL32=y #如果选择的不是libnl的1.0版本, 需要根据libnl的版本打开下面的选项
#指定库路径,要不链接找不到库
LDFLAGS += -L/opt/IPC3516EV200/libnl-3.5.0/_install/lib
LDFLAGS += -L/opt/IPC3516EV200/openssl-1.0.2s/_install/lib
make

下面是各种编译报错的处理过程:

make时报错,内容如下:

  CC  scan.c
  CC  main.c
  CC  ../src/drivers/driver_wext.c
  CC  ../src/drivers/driver_wired.c
../src/drivers/driver_nl80211.c:17:31: warning: netlink/genl/genl.h: 没有那个文件或目录
../src/drivers/driver_nl80211.c:18:31: warning: netlink/genl/ctrl.h: 没有那个文件或目录
../src/drivers/driver_nl80211.c: In function ‘nl80211_handle_alloc’:
../src/drivers/driver_nl80211.c:58: warning: implicit declaration of function ‘nl_handle_alloc_cb’
../src/drivers/driver_nl80211.c:58: warning: assignment makes pointer from integer without a cast
../src/drivers/driver_nl80211.c:68: warning: implicit declaration of function ‘nl_socket_set_local_port’

通过find . -name "genl.h"搜索如下:

root@qddytt:/opt/IPC3516EV200/libnl-3.5.0# find . -name "genl.h"
./include/netlink/genl/genl.h
./include/netlink-private/genl.h
./_install/include/libnl3/netlink/genl/genl.h

说明,有genl.h文件,原来是CFLAGS += -I/opt/IPC3516EV200/libnl-3.5.0/_install/include/添加上libnl3

然后重新make,然后又报另外的错,如下:

lrt   -lnl -lssl -lcrypto -ldl  
/mnt/sda3/arm-himix100-linux/host_bin/../lib/gcc/arm-linux-uclibceabi/6.3.0/../../../../arm-linux-uclibceabi/bin/ld: cannot find -lnl
collect2: error: ld returned 1 exit status
make: *** [wpa_supplicant] 错误 1

看一下,是这个库找不到,而上面编译出来的是libnl-3
Linux添加WIFI驱动_第4张图片

搜索一下,哪个地方指定的:
Linux添加WIFI驱动_第5张图片
找到之后,发现,需术定义宏: CONFIG_LIBNL32=y ,在.config里添加之后,再编译。没再报那个错了。现在报错如下:

  CC  wpa_passphrase.c
arm-himix100-linux-gcc  -o wpa_passphrase wpa_passphrase.o ../src/utils/common.o ../src/utils/wpa_debug.o ../src/utils/wpabuf.o ../src/utils/os_unix.o ../src/crypto/crypto_openssl.o  ../src/crypto/sha1-prf.o ../src/crypto/sha1-tlsprf.o  ../src/crypto/sha256-prf.o ../src/crypto/sha256-tlsprf.o -lrt -lcrypto
/mnt/sda3/arm-himix100-linux/host_bin/../lib/gcc/arm-linux-uclibceabi/6.3.0/../../../../arm-linux-uclibceabi/bin/ld: cannot find -lcrypto
collect2: error: ld returned 1 exit status
make: *** [wpa_passphrase] 错误 1

看最后一条出错的语句,指定了-lcrypto但没有指搜索路径,怎么找这个编译指令是哪里来的呢。看-o wpa_passphrase,去Makefile里搜索wpa_passphrase,找到了。

wpa_passphrase: $(OBJS_p)
	$(Q)$(LDO) $(LDFLAGS) -o wpa_passphrase $(OBJS_p) $(LIBS_p)
	@$(E) "  LD " $@

将libcrypto的搜索路径添加到LDFLAGS里,在.config里添加。

然后再make,不再报错,完成了。

编译Wireless Tools

为了使用命令:iwconfig,iwlist等命令。

http://www.linuxfromscratch.org/blfs/view/svn/basicnet/wireless_tools.html

整理后的编译命令如下

tar xzf wireless_tools.29.tar.gz
cd wireless_tools.29
patch -Np1 -i ../wireless_tools-29-fix_iwlist_scanning-1.patch
gedit Makefile #修改CC,AR,如下:
CC = arm-himix100-linux-gcc
AR = arm-himix100-linux-ar
make #报了很多警告,但没出错,成功完成

安装wifi相关工具

上面已将工具编出来了,如何使用呢。我采用的办法是,让设备通过nfs启动,将这些功能复制到根文件系统,然后测试命令。

将:/opt/IPC3516EV200/wireless_tools.29目录下的:iwconfig,iwlist,复制到板子的:/bin/目录。

再将libiw.so.29复制到板子的:/lib/目录。

然后,在板上测试:iwconfig,iwconfig能正常运行。

进入wpa_supplicant-2.6/wpa_supplicant目录 ,将wpa_supplicant复制到板子:/bin/目录

试运行,提示找不到库,内容如下:

/ # wpa_supplicant 
wpa_supplicant: can't load library 'libnl-3.so.200'
/ # 

将/opt/IPC3516EV200/libnl-3.5.0/_install/lib目录下的,libnl-3.so.200、libnl-3.so.200.26.0复制到板子的:/lib/目录。再运行,提示如下:

/ #  wpa_supplicant 
wpa_supplicant: can't load library 'libnl-genl-3.so.200'
/ # 

libnl-genl-3.so.200、libnl-genl-3.so.200.26.0复制到板子的:/lib/目录。再运行,提示如下:

/ #  wpa_supplicant 
wpa_supplicant: can't load library 'libssl.so.1.0.0'

将libssl.so.1.0.0复制到,板子的:/lib/目录。再运行,提示如下:

/ #  wpa_supplicant 
wpa_supplicant: can't load library 'libcrypto.so.1.0.0'

将libcrypto.so.1.0.0复制到,板子的:/lib/目录。再运行,提示如下:

/ #  wpa_supplicant 
Successfully initialized wpa_supplicant
wpa_supplicant v2.6
Copyright (c) 2003-2016, Jouni Malinen  and contributors

这次正常了。

编译RTL8188eu驱动

先下载驱动源码:https://download.csdn.net/download/u010561799/11011752

命令如下:

tar xzf rtl8188EUS_linux_v4.3.0.7_12758.20141114.tar.gz
cd rtl8188EUS_linux_v4.3.0.7_12758.20141114
gedit Makefile

查看Makefile时,发现配置项很多,认真看了发现主要是选平台。

[外链图片转存失败(img-v7U6q7V4-1569239774991)(20190828海思摄像头开发.assets/1569058777714.png)]

搜索一下对应的定义在哪里用,示例如下:

ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-linux-
KVER  := 2.6.24.7_$(ARCH)
KSRC := /usr/src/kernels/linux-$(KVER)
endif

ifeq ($(CONFIG_PLATFORM_ARM_S3C6K4), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-none-linux-gnueabi-
KVER  := 2.6.34.1
KSRC ?= /usr/src/linux-2.6.34.1
endif

根据这些示例,添加一个自己的平台,如下:

CONFIG_PLATFORM_ARM_HI3516EV200 = y #将原来CONFIG_PLATFORM_I386_PC=y改成n

ifeq ($(CONFIG_PLATFORM_ARM_HI3516EV200), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-himix100-linux-
KVER  := 4.9.37
KSRC ?= /root/hi3516ev200/Hi3516EV200_SDK_V1.0.1.0/osdrv/opensource/kernel/linux-4.9.y
endif

修改后,保存,再make,报错如下:

root@qddytt:/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114# make
make ARCH=arm CROSS_COMPILE=arm-himix100-linux- -C /root/hi3516ev200/Hi3516EV200_SDK_V1.0.1.0/osdrv/opensource/kernel/linux-4.9.y M=/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114  modules
make[1]: 正在进入目录 `/root/hi3516ev200/Hi3516EV200_SDK_V1.0.1.0/osdrv/opensource/kernel/linux-4.9.y'
  CC [M]  /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.o
In file included from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/drv_types.h:64:0,
                 from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c:22:
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c: In function 'dump_drv_version':
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/rtw_debug.h:187:19: error: void value not ignored as it ought to be
  #define _seqdump seq_printf
                   ^
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/rtw_debug.h:240:7: note: in expansion of macro '_seqdump'
    if(_seqdump(sel, fmt, ##arg)) /*rtw_warn_on(1)*/; \
       ^~~~~~~~

网上搜搜索seq_printf,发现在Linux内核的“include/linux/seq_file.h”里有定义。为了能使,对这个头文件(rtw_debug.h)里添加:

 #include 

然后重新make,还是同样报错,再仔细一下,报错是为:void value not ignored as it ought to be

意思是返回是是void,但在用反回值进行判断,如报错日志的这个:if(_seqdump(sel, fmt, ##arg)) 。

查看成printk的原型,反回值是int,而这个seq_printf的反回值是void。

采取方法为,将_seqdump重新定义为用printk的,参考PLATFORM_FREEBSD的。

[外链图片转存失败(img-753hSUWq-1569239774994)(20190828海思摄像头开发.assets/1569202348513.png)]

第一个红框注释了,添加第二个红框,再make试一下。刚才那个错没报了,现在发现了这样的报错信息,如下:

root@qddytt:/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114# make
make ARCH=arm CROSS_COMPILE=arm-himix100-linux- -C /root/hi3516ev200/Hi3516EV200_SDK_V1.0.1.0/osdrv/opensource/kernel/linux-4.9.y M=/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114  modules
make[1]: 正在进入目录 `/root/hi3516ev200/Hi3516EV200_SDK_V1.0.1.0/osdrv/opensource/kernel/linux-4.9.y'
  CC [M]  /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.o
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c: In function 'dump_drv_version':
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c:66:64: error: macro "__DATE__" might prevent reproducible builds [-Werror=date-time]
  DBG_871X_SEL_NL(sel, "build time: %s %s\n", __DATE__, __TIME__);
                                                                ^
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c:66:64: error: macro "__TIME__" might prevent reproducible builds [-Werror=date-time]
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/core/rtw_debug.c:66:64: error: macro "__DATE__" might prevent reproducible builds [-Werror=date-time]

网上搜索后,得到解决方法为,在Makile里添加:

EXTRA_CFLAGS += -Wno-error=date-time 

然后,再make,刚才那个问题未报错了。报了如下错:

  CC [M]  /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/os_dep/linux/wifi_regd.o
  CC [M]  /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/os_dep/linux/rtw_android.o
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/os_dep/linux/rtw_android.c: In function 'rtw_android_cmdstr_to_num':
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/os_dep/linux/rtw_android.c:283:11: error: implicit declaration of function 'strnicmp' [-Werror=implicit-function-declaration]
   if(0 == strnicmp(cmdstr , android_wifi_cmd_str[cmd_num], strlen(android_wifi_cmd_str[cmd_num])) )
           ^~~~~~~~
cc1: some warnings being treated as errors

根据报错的信息,将-Wno-error=implicit-function-declaration添加到Makefile,然后重新编译,报错如下:

  CC [M]  /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/hal/hal_com_phycfg.o
/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/hal/hal_com_phycfg.c:2578:6: error: 'file_path' redeclared as different kind of symbol
 char file_path[PATH_LENGTH_MAX];
      ^~~~~~~~~
In file included from ./include/linux/seq_file.h:10:0,
                 from ./include/linux/pinctrl/consumer.h:17,
                 from ./include/linux/pinctrl/devinfo.h:21,
                 from ./include/linux/device.h:24,
                 from ./include/linux/dmaengine.h:20,
                 from ./include/linux/netdevice.h:38,
                 from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/osdep_service_linux.h:35,
                 from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/osdep_service.h:41,
                 from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/include/drv_types.h:32,
                 from /opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/hal/hal_com_phycfg.c:22:
./include/linux/fs.h:2719:14: note: previous declaration of 'file_path' was here
 extern char *file_path(struct file *, char *, int);
              ^~~~~~~~~
make[2]: *** [/opt/IPC3516EV200/rtl8188EUS_linux_v4.3.0.7_12758.20141114/hal/hal_com_phycfg.o] 错误 1

这个错,在linux内核的fs.h定义为了函数,这hal_com_phycfg.c:2578定义成了变量,将它改成前面加个static试一下。还是会报这个错,使用宏替换,在变量定义的前面加上#define file_path myfile_path 再试一下,编译后未报错,生成了ko文件。

将生成的8188eu.ko放到nfs文件系统下,加载试一下。报错这样:

/ko # insmod 8188eu.ko 
8188eu: Unknown symbol strnicmp (err 0)
insmod: can't insert '8188eu.ko': unknown symbol in module, or unknown parameter

回想一下,之前编译时,提示strnicmp是隐式定义的,强制不报错的,现在找不到这个函数。网上有说:

strnicmp 没有定义 改为 strncasecmp 试一下。改了之后,重新make,编译通过了。再试insmod,成功了,如下所示:

/ko # insmod 8188eu.ko 
RTL871X: module init start
RTL871X: rtl8188eu v4.3.0.7_12758.20141114
RTL871X: build time: Sep 23 2019 17:05:10
usbcore: registered new interface driver rtl8188eu
RTL871X: module init ret=0
/ko # 

你可能感兴趣的:(编程)