admin管理员组

文章数量:1531934

本文主要记录给Baytrail 平台 Android6.0系统移植EWM-W163M201E WiFi的过程和中间遇到的问题。Android版本是6.0,Kernel版本是3.14.64,CPU是 Bay Trail平台Vallyview-D/M系列,WiFi是研华的EWM-W163M201E模块。

  • 驱动下载

WiFi驱动一般都是wifi 厂商提供的,一般情况下厂商会提供wifi驱动,wifi firmware和wifi potting guide等资料给软件工程师 。本次使用的EWM-W163M201E wifi模块的Main Chipset是 QCA6174A 它需要的驱动是ath10k。厂商说这个驱动是包含在Linux源码中的,但是通过查看源码发现我们的3.14.64 kernel里面的ath10k驱动由于版本较低的缘故还没有添加QCA6174A 的支持。那么就遇到一个比较尴尬的事情,没有任何驱动也没有任何资料可以使用参考。没办法我就查找各种资料幸好功夫不负有心人我找到了compat-wireless驱动源码,发现里面有我们需要的驱动。我们就从下面路径下载了comat-wireless驱动compat-wireless-2017-09-25.tar.xz,然后单独编译移植到我们的系统。

compat-wireless驱动下载地址:http://mirror2.openwrt/sources/

  • 驱动编译
  1. 修改顶层Makefile
    下载到驱动源码后首先需要通过修改顶层Makefile中的KMODDIR,KLIB,KMODPATH_ARG,KLIB_BUILD等变量来设置kernel路径和驱动安装路径(这里和后面说的安装路径都是指编译后的驱动存放路径,编译Android的时候会把这个安装路径下的驱动和lib库等文件打包到相关Image中),以确保驱动可以正常编译和安装到你的Android系统中。如下是我的修改可做参考
    --- a/compat-wireless-2017-09-25/Makefile	2017-09-29 04:51:19.000000000 +0800
    +++ b/compat-wireless-2017-09-25/Makefile	2019-01-15 17:29:54.336700189 +0800
    @@ -8,14 +8,18 @@ MAKEFLAGS += --no-print-directory
     SHELL := /bin/bash
     BACKPORT_DIR := $(shell pwd)
     
    -KMODDIR ?= updates
    +KMODDIR = kernel
     ifneq ($(origin KLIB), undefined)
     KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)"
     else
    -KLIB := /lib/modules/$(shell uname -r)/
    +KLIB := "/home/work/Android_BSP/byt_mr_2016ww32/device/advantech/upos-kernel/x86_64/"
    -KMODPATH_ARG :=
    +KMODPATH_ARG := "INSTALL_MOD_PATH=$(KLIB)"
     endif
    -KLIB_BUILD ?= $(KLIB)/build/
    +KLIB_BUILD = "/home/work/Android_BSP/byt_mr_2016ww32/device/advantech/upos-kernel/linux"
     KERNEL_CONFIG := $(KLIB_BUILD)/.config
     KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
     CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
    
  2. 配置编译选项 
    通过make menuconfig来配置我们需要的编译选项。我需要编译cfg80211,mac80211,ath10,ath10_core,ath10_pci等驱动。如下是我的操作可供参考

  3. 编译和安装
    上面配置好后就可以分别执行make和make install命令编译和安装驱动了。我设置的驱动放置路径为x86_64,那么如下是我编译安装后看到的驱动
  • Android相关修改

Android相关修改主要包括添加wifi firmware,hardware层修改,framwork层修改,wpa_supplicant服务添加等。下面我们逐一来介绍。

  1. wifi firmware
    wifi驱动加载的时候一般都需要添加firmware的,而firmware一般也是由厂商提供的。奇葩的是PM也没有问厂商要到firmware。那怎么办呢?那我就各种的找,真是柳暗花明又一村我发现安装Ubuntu系统后该模块是可以使用的。所以我就查看Ubuntu系统的dmesg,终于找到了ubuntu系统中使用的QCA6174A相关firmware,然后把他拷贝了出来。有了firmware只需要将它拷贝到系统指定的路径即可,加载驱动的时候就会自动在相关路径寻找并加载。下面是我的添加可供参考
    --- a/device/advantech/upos/upos.mk
    +++ b/device/advantech/upos/upos.mk
    @@ -68,6 +68,18 @@ PRODUCT_COPY_FILES += \
     	$(LOCAL_PATH)/third_party/busybox-x86_64:system/bin/busybox-x86_64 \
     	$(LOCAL_PATH)/third_party/busybox-x86_64:system/bin/busybox
     
    +PRODUCT_COPY_FILES += \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/board.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/board.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/board-2.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/board-2.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/firmware-4.bin:system/vendor/firmware/ath10k/QCA6174/hw3.0/firmware-4.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw3.0/notice_ath10k_firmware-4.txt:system/vendor/firmware/ath10k/QCA6174/hw3.0/notice_ath10k_firmware-4.txt \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/board.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/board.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/board-2.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/board-2.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/firmware-5.bin:system/vendor/firmware/ath10k/QCA6174/hw2.1/firmware-5.bin \
    +	$(LOCAL_PATH)/third_party/ath10k/QCA6174/hw2.1/notice_ath10k_firmware-5.txt:system/vendor/firmware/ath10k/QCA6174/hw2.1/notice_ath10k_firmware-5.txt \
    +	$(LOCAL_PATH)/third_party/ath10k/ath10k.conf:system/etc/modprobe.d/ath10k.conf 
    +
    +
     PRODUCT_PACKAGES += \
         AndroidTerm \
         libjackpal-androidterm4 \
    需要注意的是给系统的system/etc/modprobe.d/路径下还拷贝了ath10k.conf文件,该文件只有一条命令,但是是必须添加的因为发现如果不添加驱动加载的时候会报错
    options ath10k_core skip_otp=y
  2. hardware层修改
    WiFi相关代码在hardware层的分为两部分。一部分是/libhardware_legacy/wifi.c。这部分代码是wifi驱动加载卸载,firmware存放路径和加载,wifi socket通信等相关处理的关键。另一部分是/hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib。它里面的driver_cmd_nl80211.c是驱动和wpa_supplicant通信的关键。kernel和wpa_supplicant之间的交互一般都有固定的驱动接口如WEXT、NL80211。QCA6174A的驱动接口是NL80211,而/hardware/qcom/wlan/qcwcn/wpa_supplicant_8_lib正是QCA6174A需要的NL80211代码。需要在BoardConfig.mk中配置一下才可以编译和使用指定的wpa_supplicant_8_lib。如下是我的配置
    --- a/device/advantech/upos/BoardConfig.mk
    +++ b/device/advantech/upos/BoardConfig.mk
    @@ -207,6 +207,19 @@ BOARD_HAVE_BLUETOOTH_LINUX := false
     
     BOARD_KERNEL_CMDLINE += acpi_backlight=video
     
    +##############################################################
    +# Source: device/intel/mixins/groups/wlan/autodetect/BoardConfig.mk
    +##############################################################
    +ADDITIONAL_DEFAULT_PROPERTIES += wifi.interface=wlan0
    +#WPA_SUPPLICANT_VERSION := VER_2_1_DEVEL
    +WPA_SUPPLICANT_VERSION := VER_0_8_X
    +BOARD_WPA_SUPPLICANT_DRIVER := NL80211
    +#WIFI_DRIVER_MODULE_PATH ?= auto
    +#BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_rtl
    +BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_qcwcn
    +BOARD_WLAN_DEVICE := qcwcn
    +DEVICE_PACKAGE_OVERLAYS += device/intel/common/wlan/overlay-wifi-display
    +
     DEVICE_PACKAGE_OVERLAYS += device/intel/common/audio/overlay
     DEVICE_PACKAGE_OVERLAYS += device/intel/common/audio/overlay-no-ultrasound
     
  3. framwork层修改
    系统网络选项配置和优先级的配置实在/frameworks/base/core/res/res/values/config.xml文件中的,不过我们通常的做法是不直接修改frameworks中的该文件,而是在平台代码中添加相关文件然后编译系统的时候以overlay的方式来修改它,那么下面是我们的修改
    --- a/device/intel/common/wlan/overlay-wifi-display/frameworks/base/core/res/res/values/config.xml
    +++ b/device/intel/common/wlan/overlay-wifi-display/frameworks/base/core/res/res/values/config.xml
    @@ -14,4 +14,50 @@
         -->
         <bool name="config_enableWifiDisplay">true</bool>
     
    +    <!-- This string array should be overridden by the device to present a list of network
    +                  attributes.  This is used by the connectivity manager to decide which networks can coexist
    +         based on the hardware -->
    +    <!-- An Array of "[Connection name],[ConnectivityManager.TYPE_xxxx],
    +                  [associated radio-type],[priority],[restoral-timer(ms)],[dependencyMet]  -->
    +    <!-- the 5th element "resore-time" indicates the number of milliseconds to delay
    +                  before automatically restore the default connection.  Set -1 if the connection
    +         does not require auto-restore. -->
    +    <!-- the 6th element indicates boot-time dependency-met value. -->
    +    <string-array translatable="false" name="networkAttributes">
    +        <item>"wifi,1,1,1,-1,true"</item>
    +        <item>"mobile,0,0,0,-1,true"</item>
    +        <item>"mobile_mms,2,0,2,60000,true"</item>
    +        <item>"mobile_supl,3,0,2,60000,true"</item>
    +        <item>"mobile_hipri,5,0,3,60000,true"</item>
    +        <item>"ethernet,9,9,1,-1,true"</item>
    +        <item>"mobile_fota,10,0,2,60000,true"</item>
    +        <item>"mobile_ims,11,0,2,60000,true"</item>
    +        <item>"mobile_cbs,12,0,2,60000,true"</item>
    +        <item>"wifi_p2p,13,1,0,-1,true"</item>
    +    </string-array>
    +    <!-- This string array should be overridden by the device to present a list of radio
    +                  attributes.  This is used by the connectivity manager to decide which networks can coexist
    +         based on the hardware -->
    +    <!-- An Array of "[ConnectivityManager connectionType],
    +                               [# simultaneous connection types]"  -->
    +    <string-array translatable="false" name="radioAttributes">
    +        <item>"1,1"</item>
    +        <item>"0,1"</item>
    +        <item>"9,1"</item>
    +    </string-array>
    +
    +    <!-- Set of NetworkInfo.getType() that reflect data usage. -->
    +    <integer-array translatable="false" name="config_data_usage_network_types">
    +        <item>0</item> <!-- TYPE_MOBILE -->
    +        <item>2</item> <!-- TYPE_MOBILE_MMS -->
    +        <item>3</item> <!-- TYPE_MOBILE_SUPL -->
    +        <item>4</item> <!-- TYPE_MOBILE_DUN -->
    +        <item>5</item> <!-- TYPE_MOBILE_HIPRI -->
    +        <item>9</item> <!-- TYPE_ETHERNET -->
    +        <item>10</item> <!-- TYPE_MOBILE_FOTA -->
    +        <item>11</item> <!-- TYPE_MOBILE_IMS -->
    +        <item>12</item> <!-- TYPE_MOBILE_CBS -->
    +    </integer-array>
    +
    +
     </resources>
  4. wpa_supplicant服务添加
    wpa_suppulicant服务是wifi模块在HAL层和framework层通信的关键,它是一个后台运行的服务。源码在/external/wpa_supplicant_8/wpa_supplicant/目录下,我们需要在device目录的平台代码的makefile中添加编译选项,如下是我们添加的
    --- a/device/advantech/upos/device.mk
    +++ b/device/advantech/upos/device.mk
    @@ -303,6 +303,19 @@ PRODUCT_COPY_FILES += \
     PRODUCT_PACKAGES += \
         audio.a2dp.default
     
    +##############################################################
    +# Source: device/intel/mixins/groups/wlan/autodetect/product.mk
    +##############################################################
    +PRODUCT_COPY_FILES += \
    +    device/intel/common/wlan/wpa_supplicant-common.conf:system/etc/wifi/wpa_supplicant.conf \
    +    device/intel/common/wlan/wpa_supplicant_overlay.conf:system/etc/wifi/wpa_supplicant_overlay.conf \
    +	frameworks/native/data/etc/android.hardware.wifi.xml:system/etc/permissions/android.hardware.wifi.xml
    +	#frameworks/native/data/etc/android.hardware.wifi.direct.xml:system/etc/permissions/android.hardware.wifi.direct.xml
    +
    +PRODUCT_PACKAGES += \
    +		wpa_supplicant 
    +
    +
     # Tinyalsa
     PRODUCT_PACKAGES_DEBUG += \
             tinymix \
    上面出来添加wpa_supplicant的编译外还将需要的wpa_cupplicant.conf配置文件也拷贝到了系统指定目录,另外frameworks/native/data/etc/android.hardware.wifi.xml和frameworks/native/data/etc/android.hardware.wifi.direct.xml分别代表的是设备是否支持wifi功能和wifi直连功能,如果不添加android.hardware.wifi.xml的话在Setting中就无法看到WIFI选项。
    编译了wpa_supplicant后,就需要添加一个后台服务来运行它,并且需要添加获取IP的服务。如下是我的添加:
    --- a/device/advantech/upos/init.rc
    +++ b/device/advantech/upos/init.rc
    @@ -14,6 +14,12 @@ on post-fs-data
     on post-fs-data
         setprop persist.sys.root_access 3
     
    +on post-fs-data
    +	mkdir /data/misc/wifi 0770 wifi wifi
    +	mkdir /data/misc/wifi/sockets 0770 wifi wifi
    +	mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi
    +	mkdir /data/misc/dhcp 0770 dhcp dhcp
    +
     on boot
         setprop service.adb.tcp.port 5555
     
    @@ -214,6 +220,42 @@ on post-fs-data
     
     import /init.debug-charging.rc
     
    +
    +service wpa_supplicant /system/bin/wpa_supplicant -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
    +	-O/data/misc/wifi/sockets -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0
    +	class main
    +	socket wpa_wlan0 dgram 660 wifi wifi
    +	disabled
    +
    +
    +#setprop wifi.supplicant wpa_supplicant
    +
    +
    +service dhcpcd_wlan0 /system/bin/dhcpcd -aABDKL
    +	class main
    +	disabled
    +	oneshot
    +
    +service iprenew_wlan0 /system/bin/dhcpcd -n
    +	class main
    +	disabled
    +	oneshot
    +
    +on property:init.svc.wpa_supplicant=stopped
    +    stop dhcpcd
    +
     on fs
         mkdir /dev/pstore 0755 root system
         mount pstore pstore /dev/pstore

 

  • 其他修改

我们在移植的时候发现系统状态栏的网络状态显示不正常,老是存在一个感叹号,但是网络却是可以使用的。经过追踪代码发现是Android网络的验证机制导致的。Android系统可以通过Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED全局变量来控制网络连接以后是否需要进行网络可用性检查。如果该值被设置为1或者没有设置该值则系统会通过访问Settings.Global.CAPTIVE_PORTAL_SERVER全局变量指定的网址来判断网络是否可用。如果全局变量Settings.Global.CAPTIVE_PORTAL_SERVER没有被设置系统则会使用默认的DEFAULT_SERVER="connectivitycheck.gstatic"网址测试。那么问题就出在这里,国内由于某种原因这个网址有时可用连接上有时连接不上,所以当连接不上的时候无论是Ethernet网络、WiFi网络还是3G/4G网络,它的状态栏图标都会有感叹号。想了解这部分可以参考/frameworks/base/services/core/java/com/android/server/connectivity/NetworkMonitor.java代码。那么问题找到了该怎么解决呢?一般有下面两种方法可以解决:

  1. 方法一
    通过设置Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED为0将网络检查取消掉,但是这样会存在一个问题。当我们连接的Ethernet网络或者网络需要网络认证才可以使用的话,我们就无法进入到这个网络认证界面了,也就是说无法认证连接网络了。
  2. 方法二:
    设置Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED为1,并将Settings.Global.CAPTIVE_PORTAL_SERVER设置为一个国内可用的网络地址即可。这里需要注意的是Settings.Global.CAPTIVE_PORTAL_SERVER不是随便设置个网址就可以的,它必须是一个可以返回204状态码的网址。

那么我们就是使用第二种方法解决了这个问题的。做法如下:

--- a/device/advantech/upos/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
+++ b/device/advantech/upos/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml
@@ -22,6 +22,12 @@
     <bool name="def_wake_gesture_enabled">false</bool>
 
     <!-- Keep screen on at all times by default -->
    <bool name="def_stay_on_while_plugged_in">true</bool>
+
+	<add-resource type="integer" name="def_captive_portal_detection_enable" />
+	<integer name="def_captive_portal_detection_enable">1</integer>
+	
+	<add-resource type="string" name="def_captive_portal_server" />
+    <string name="def_captive_portal_server">204.gentool.top</string>
         
 </resources>
--- a/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2576,6 +2576,12 @@ class DatabaseHelper extends SQLiteOpenHelper {
             loadBooleanSetting(stmt, Settings.Global.ASSISTED_GPS_ENABLED,
                     R.bool.assisted_gps_enabled);
 
+			loadIntegerSetting(stmt, Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED,
+                    R.integer.def_captive_portal_detection_enable);
+
+			loadStringSetting(stmt, Settings.Global.CAPTIVE_PORTAL_SERVER,
+                    R.string.def_captive_portal_server);
+
             loadBooleanSetting(stmt, Settings.Global.AUTO_TIME,
                     R.bool.def_auto_time); // Sync time to NITZ
 

 

 

本文标签: AtherosQualcommQCA6174ASupportModel