Freescale i.MX 6 MNC平台移植BT/WIFI驱动

时间:2021-05-13 09:26:48

       此项目之前移植到Android6.0.1版本。基本系统可以起来了。现在要调一下WiFi和Bluetooth。此板上用的是Broadcom BCM89335的WiFi和Bluetooth二合一芯片。WiFi通过4线SDIO和SoC相连接,Bluetooth通过UART和SoC相连接。芯片的框图如下:

 

       WiFi部分的电路图如下:

 

       SoC侧接的是SD3的SD3_DAT0 ~SD3_DAT3, SD3_CLK及SD3_CMD。

 

       根据电路图,WL_REG_ON接到SoC的A19(NANDF_D4)PIN,查IOMux_Tool,此PIN对应的GPIO为GPIO2_4。

 

配置WiFi 相关的DTS及Kernel

       有了以上数据,就可以开始配置DTS文件了。修改/kernel_imx/arch/arm/boot/imx6dq-sabresd.dtsi文件。找到WL_REG_ON的配置wlreg_on,修改gpio的值为gpio2_4。

              wlreg_on:fixedregulator@100 {

                     compatible= "regulator-fixed";

                     regulator-min-microvolt= <5000000>;

                     regulator-max-microvolt= <5000000>;

                     regulator-name= "wlreg_on";

-            gpio = <&gpio4 7 0>;

+            gpio = <&gpio2 4 0>;

           startup-delay-us = <100>;

           enable-active-high;

      };

 

       找到SDIO 3的PIN配置pinctl_usdhc3,把DAT4~DAT7删除,增加GPIO2_4为GPIO模式。

              pinctrl_usdhc3:usdhc3grp {

                     fsl,pins= <

                            MX6QDL_PAD_SD3_CMD__SD3_CMD           0x17059

                            MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059

                            MX6QDL_PAD_SD3_DAT0__SD3_DATA0       0x17059

                            MX6QDL_PAD_SD3_DAT1__SD3_DATA1       0x17059

                            MX6QDL_PAD_SD3_DAT2__SD3_DATA2       0x17059

                            MX6QDL_PAD_SD3_DAT3__SD3_DATA3       0x17059

-               MX6QDL_PAD_SD3_DAT4__SD3_DATA4         0x17059

-               MX6QDL_PAD_SD3_DAT5__SD3_DATA5         0x17059

-               MX6QDL_PAD_SD3_DAT6__SD3_DATA6         0x17059

-                MX6QDL_PAD_SD3_DAT7__SD3_DATA7          0x17059

+               MX6QDL_PAD_NANDF_D4__GPIO2_IO04       0x13069  /* WL_REG_ON */

          >;

 

       找到SDIO3 的配置usdhc3,把bus-width改为4,增加wifi-host。

&usdhc3 {

       pinctrl-names= "default";

       pinctrl-0= <&pinctrl_usdhc3>;

-    bus-width = <8>;

+    bus-width = <4>;

       cd-gpios= <&gpio2 0 0>;

       wp-gpios= <&gpio2 1 0>;

       no-1-8-v;

+     wifi-host;

+     pm-ignore-notify;

       keep-power-in-suspend;

       enable-sdio-wakeup;

       status= "okay";

};

 

       另外搜索到usdhc5中也写了wifi-host,把它删除。

&uart5 {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_uart5_1>;

@@ -1070,25 +1084,25 @@

       cd-gpios = <&gpio2 2 0>;

       wp-gpios = <&gpio2 3 0>;

       no-1-8-v;

-       wifi-host;

-       pm-ignore-notify;

       keep-power-in-suspend;

        enable-sdio-wakeup;

-       status = "okay";

+       status = "disabled";

 };

 

       wifi-host标志是驱动程序用来识别此SDIO是否连接有WiFi模块的标志。具体代码可参考drivers/mmc/host/sdhci-esdhc-imx.c文件中的sdhci_esdhc_imx_probe_dt()函数。

       if (of_get_property(np, "wifi-host",NULL)) {

                wifi_mmc_host = host->mmc;

                dev_info(mmc_dev(host->mmc),"assigned as wifi host\n");

       }

 

       if (of_get_property(np, "pm-ignore-notify", NULL)) {

                host->mmc->pm_caps |=MMC_PM_IGNORE_PM_NOTIFY;

        }

 

       所以为了避免出现干扰,系统中只保留了一个wifi-host的SDIO配置。

 

       配置Kernel配置文件arch/arm/comfigs/imx_v7_android_defconfig文件。把CONFIG_BCMDHD打开,其它的没用的关闭。

CONFIG_USB_NET_CDC_EEM=y

-CONFIG_ATH_CARDS=m

-CONFIG_ATH6KL=m

-CONFIG_ATH6KL_SDIO=m

-# CONFIG_BCMDHD is notset

+# CONFIG_ATH_CARDSis not set

+# CONFIG_ATH6KL isnot set

+# CONFIG_ATH6KL_SDIOis not set

+CONFIG_BCMDHD=y

 CONFIG_BCMDHD_SDIO=y

 CONFIG_BCMDHD_FW_PATH="/system/etc/firmware/bcm/fw_bcmdhd.bin"

 CONFIG_BCMDHD_NVRAM_PATH="/system/etc/firmware/bcm/bcmdhd.cal"

-CONFIG_BRCMFMAC=m

-CONFIG_RTL8821AS=m

+CONFIG_BRCMFMAC=y

+# CONFIG_RTL8821ASis not set

 #CONFIG_INPUT_MOUSEDEV_PSAUX is not set

 

       至此,Kernel部分的配置算完成了。接下来需要移植驱动了。

 

移植Supplicant

       从Broadcom网上下载了最新的驱动文件包BCM89335_DHD_141_91_FW_AARD01SRC41_6_37_39_38_Supp_126_wapi.7z,解开看了一下,主要分两部分,Supplicant和Driver,决定先移植Supplicant。

 

       Supplicant也分为两类,一种是支持WAPI的,另一个是不支持的,为了简单起见,选择了HOSTAP_REL_0_8_0_126.tar.gz这个不支持WAPI的版本。解开移到external目录下。

 

       tar zxvf HOSTAP_REL_0_8_0_126.tar.gz

       mv HOSTAP_REL_0_8_0_126  external/

 

       看了一下里面的移植说明,建立符号链接

       cd external/HOSTAP_REL_0_8_0_126/libbcmhd

       ln -s ../src .

 

       因为原先系统中已经有了一份wpa_supplicant,所以默认应该不会被编译到,或者会把模块重定义,所以需要先把系统中老的wpa_supplicant屏蔽掉。修改external/wpa_supplicant/Android.mk文件。注释掉编译。

--- a/external/wpa_supplicant_8/Android.mk

+++ b/external/wpa_supplicant_8/Android.mk

@@ -1,9 +1,9 @@

 LOCAL_PATH:= $(call my-dir)

 

-ifndefWPA_SUPPLICANT_VERSION

-WPA_SUPPLICANT_VERSION:= VER_0_8_X

-endif

-ifeq($(WPA_SUPPLICANT_VERSION),$(filter$(WPA_SUPPLICANT_VERSION),VER_0_8_X VER_0_8_UNITE))

+#ifndefWPA_SUPPLICANT_VERSION

+#WPA_SUPPLICANT_VERSION:= VER_0_8_X

+##endif

+ifneq($(WPA_SUPPLICANT_VERSION),$(filter$(WPA_SUPPLICANT_VERSION),VER_0_8_X VER_0_8_UNITE))

 #The order of the 2 Android.mks does matter!

 #TODO: Clean up the Android.mks, reset all the temporary variables at the

 #end of each Android.mk, so that one Android.mk doesn't depend on variables

 

       编译,报错,提示keystore-engine什么的没有定义,搜了一下,发现此函数在/system/security/keystore-engine下定义。根据这个Android.mk,会生成libkeystore-engine.so文件。

ifeq($(OPENSSL_FLAVOR),BoringSSL)

 LOCAL_MODULE := libkeystore-engine

 

 LOCAL_SRC_FILES := \

       android_engine.cpp

else

 LOCAL_MODULE := libkeystore

 

 LOCAL_MODULE_RELATIVE_PATH := ssl/engines

 

 LOCAL_SRC_FILES := \

       eng_keystore.cpp \

       keyhandle.cpp \

       ecdsa_meth.cpp \

       dsa_meth.cpp \

       rsa_meth.cpp

 

 LOCAL_C_INCLUDES += \

       external/openssl/include \

       external/openssl

endif

 

LOCAL_MODULE_TAGS := optional

LOCAL_CFLAGS := -fvisibility=hidden -Wall-Werror

 

LOCAL_SHARED_LIBRARIES += \

       libcrypto \

       liblog \

       libcutils \

       libutils \

       libbinder \

       libkeystore_binder

 

LOCAL_ADDITIONAL_DEPENDENCIES :=$(LOCAL_PATH)/Android.mk

 

include$(BUILD_SHARED_LIBRARY)

 

       找了一下OPENSSL_FLAVOR这个定义,发现在external/boringssl/flavor.mk中定义为BoringSSL了。

external/boringssl/flavor.mk:4:OPENSSL_FLAVOR=BoringSSL

 

       另外在out目录下搜索了一下,发现这个.so文件已经生成了。那应该把它Link增加此库就可以了。

 

       修改external/HOSTAP_REL_0_8_0_126/wpa_supplicant/Android.mk文件。打开这文件一看,发现问题了。此Makefile最高只支持到Android 5.1,Android 6.0.1还没有在此支持列表中,看来Broadcom 也是够懒的。那就自己改吧。

 

       查找此文件中所以带ifneq($(findstring 5.1,$(PLATFORM_VERSION)),)的部分,拷贝一份,把5.1改为6.0,另外,在链接库的地方增加我们所需要的keystore-engine。改完后如下。

--- a/external/HOSTAP_REL_0_8_0_126/wpa_supplicant/Android.mk

+++b/external/HOSTAP_REL_0_8_0_126/wpa_supplicant/Android.mk

@@ -169,6 +169,10 @@ ifneq ($(findstring5.1,$(PLATFORM_VERSION)),)

 #for lollipop

 L_CFLAGS += -DLP

 endif

+ifneq ($(findstring6.0,$(PLATFORM_VERSION)),)

+# for lollipop

+L_CFLAGS += -DLP

+endif

 

 INCLUDES = $(LOCAL_PATH)

 INCLUDES += $(LOCAL_PATH)/src

@@ -1775,6 +1779,9 @@LOCAL_SHARED_LIBRARIES += $(LIB_SHARED_EAP_PROXY)

 endif

 ifeq($(CONFIG_TLS), openssl)

 LOCAL_SHARED_LIBRARIES += libcrypto libssl

+ifneq ($(findstring6.0,$(PLATFORM_VERSION)),)

+LOCAL_SHARED_LIBRARIES+= libkeystore_binder libkeystore-engine

+endif

 

       再编译,通过了,已经生成了wpa_supplicant、wpa_cli及libwpa_client.so文件。

 

拷贝配置文件

       还需要把新的配置文件及bin拷贝到系统的指定目录下,供wpa_supplicant启动时使用。修改device/fsl/sabresd_6dq/BoardConfig.mk文件,增加相关文件拷贝:

--- a/device/fsl/sabresd_6dq/BoardConfig.mk

+++ b/device/fsl/sabresd_6dq/BoardConfig.mk

@@ -47,7 +47,8 @@ PRODUCT_MODEL :=SABRESD-MX6DQ

 TARGET_RELEASETOOLS_EXTENSIONS :=device/fsl/imx6

 #UNITE is a virtual device support both atheros and realtek wifi(ar6103 andrtl8723as)

 BOARD_WLAN_DEVICE            := UNITE

-WPA_SUPPLICANT_VERSION       := VER_0_8_UNITE

+#WPA_SUPPLICANT_VERSION       := VER_0_8_UNITE

+WPA_SUPPLICANT_VERSION       := VER_0_8_X

 

 BOARD_WPA_SUPPLICANT_DRIVER  := NL80211

 BOARD_HOSTAPD_DRIVER         := NL80211

@@ -137,3 +138,33 @@ BOARD_SEPOLICY_DIRS :=\

 

 PRODUCT_PROPERTY_OVERRIDES += \

    sys.def_screen_time=-1

+

+#wifi

+PRODUCT_PACKAGES +=\

+       bcm4339_mfg.bin \

+       bcm4339_sta_p2p.bin \

+       bcmdhd_apsta.bin \

+       nvram.txt \

+       bcmdhd.ko \

+       cfg80211.ko \

+       compat.ko \

+       hostapd.conf \

+       p2p_supplicant.conf \

+       wpa_supplicant.conf \

+       hostapd \

+       wpa_supplicant \

+       insmod_ap.sh \

+       insmod_stap2p.sh \

+       bcmdhd.cal \

+       wl

+

+PRODUCT_COPY_FILES+=  \

+      device/fsl/sabresd_6dq/wifi/wpa_supplicant_ap.conf:system/etc/wifi/wpa_supplicant_ap.conf\

+       device/fsl/sabresd_6dq/wifi/wpa_supplicant.conf:system/etc/wifi/wpa_supplicant.conf\

+      device/fsl/sabresd_6dq/wifi/p2p_supplicant.conf:system/etc/wifi/p2p_supplicant.conf\

+      device/fsl/sabresd_6dq/wifi/sta.conf:system/etc/wifi/sta.conf \

+      device/fsl/sabresd_6dq/wifi/fw_bcmdhd_hu.bin:system/etc/wifi/firmware/fw_bcmdhd_hu.bin\

+      device/fsl/sabresd_6dq/wifi/fw_bcmdhd_hu_acs.bin:system/etc/wifi/firmware/fw_bcmdhd_hu_acs.bin\

+      device/fsl/sabresd_6dq/wifi/fw_bcmdhd_mfgtest.bin:system/etc/wifi/firmware/fw_bcmdhd_mfgtest.bin\

+      device/fsl/sabresd_6dq/wifi/fw_bcmdhd_rse.bin:system/etc/wifi/firmware/fw_bcmdhd_rse.bin\

+      #device/fsl/sabresd_6dq/modules/bcmdhd.ko:system/lib/modules/bcmdhd.ko

 

       把相关文件conf,bin 拷贝到device/fsl/sabresd_6dq/wifi目录下。

 

       编译好系统,下载到设备中,Wifi已经可以打开工作了。但驱动还没有更新。

 

更新WiFi Driver

       虽然已经可以用了,但Driver还是老的,最好同步更新一下。

 

       解开bcmdhd文件,拷贝到kernel_imx/drivers/net/wireless目录下同名目录。

 

       编译出错。__DATE__, __TIME__不认识。打开bdmdhd/dhd_common.c文件,注释掉

const char dhd_version[] = "DongleHost Driver, version " EPI_VERSION_STR;

       //DHD_COMPILED" on " __DATE__ " at " __TIME__;

 

       编译通过,下载后发现Wifi不能工作了。看了一下Log,提示找不到platform_data,打开bcmdhd/dhd_linux_platdev.c文件。看了一下,需要打开CONFIG_DTS。

 

       对比了一下bdmdhd/Makefile文件,把不同的地方仔细看了一下。又参考了一下Porting Guide,主要有:

CONFIG_DTS: 表明系统是用dts还是老式的platform_data;在示例的dts代码中,还有一个GPIO是用于中断的。由于本系统中没有此GPIO,所以可以在dts文件中随便写一个不用的GPIO或者在bcmdhd/dhd_linux_platdev.c文件中wifi_plat_dev_drv_probe()函数中把相关的部分注释掉:

#if 0

       /* This is to get the irq for the OOB */

       gpio = of_get_gpio(pdev->dev.of_node,0);

 

       if (gpio < 0) {

              DHD_ERROR(("%s gpioinformation is incorrect\n", __FUNCTION__));

              return -1;

       }

       irq = gpio_to_irq(gpio);

       if (irq < 0) {

              DHD_ERROR(("%s irqinformation is incorrect\n", __FUNCTION__));

              return -1;

       }

       adapter->irq_num = irq;

 

       /* need to change the flags according toour requirement */

       adapter->intr_flags = IORESOURCE_IRQ |IORESOURCE_IRQ_HIGHLEVEL |

              IORESOURCE_IRQ_SHAREABLE;

#endif

 

另外由于没有中断GPIO,所以在Makefile中把_DOOB_INTR_ONLY及-DHW_OOB去掉,加上-DSDIO_ISR_THREAD。

 

       由于Kernel版本是v3.14.52,所以需要增加wl_cfgvendor.c文件到Makefile文件中。

 

       以上修改完成,编译没有错误了,下载到设备中,没找到设备。看来是检测Wifi设备的代码有问题,查看bcmdhd/dhd_linux_platdev.c文件中的wifi_platform_bus_enumerate()这个函数,检测硬件是在此进行的。看了一下代码,还是根据platform_data来进行的,现在DTS方式的话就不行了。

intwifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present)

{

       interr = 0;

       structwifi_platform_data *plat_data;

 

       if(!adapter || !adapter->wifi_plat_data)

              return-EINVAL;

       plat_data= adapter->wifi_plat_data;

 

       DHD_ERROR(("%sdevice present %d\n", __FUNCTION__, device_present));

       if(plat_data->set_carddetect) {

              err= plat_data->set_carddetect(device_present);

       }

       returnerr;

}

       参考了一下之前的代码,改成如下:

intwifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present)

{

       interr = 0;

       structwifi_platform_data *plat_data;

 

       if (!adapter) {

              pr_err("!!!!%s: failed!  adapter variable isNULL!!!!!\n", __FUNCTION__);

              return-EINVAL;

       }

 

       DHD_ERROR(("%sdevice present %d\n", __FUNCTION__, device_present));

 

       if (!adapter->wifi_plat_data) {

              wifi_card_detect(); /* hook for card_detect */

       }else {

              plat_data= adapter->wifi_plat_data;

              if(plat_data->set_carddetect)

                     err= plat_data->set_carddetect(device_present);

       }

 

       return0; /* force success status returned */

}

 

       调用wifi_card_detect()函数来检测硬件,此函数定义在之前写dts时提到过的drivers/mmc/host/sdhci-esdhc-imx.c文件中。

 

       重新编译下载,再测试,WiFi就一切正常了。WiFi驱动移植算基本完成。

 

       现在遗留的问题是WAPI驱动没有整合,因为手上没有WAPI测试设备,另外加上WAPI的话,以后每台还需要付License费用的。所以暂时就不加了。

 

关于编译成模块ko的问题

       之前为了方便调试,想把驱动编译成ko文件,但在Kernel配置文件中把CONFIG_BCMDHD改为m,编译完成后根本没有生成ko文件。一开始以为是有其它依赖关系引起的,但另一个平台如此修改就能够正常生成,后来对比了一下,发现kernel/drivers/net/wireless/bcmdhd/Makefile中有一行。

##########################

# driver type

# m: module type driver

# y: built-in type driver

##########################

DRIVER_TYPE ?= y

 

       需要把它改为

DRIVER_TYPE ?= m

 

       这也算是一个小插曲吧。

 

Bluetooth部分原理图

       接下来要调试Bluetooth了。Freescale的驱动包里Bluetooth部分完全是空白。文档也没有,代码也没有。估计现系统中的代码应该是可用的。要不然就麻烦大了。还是先查原理图。音频部分暂时先不管,只看通信部分的。

 

       Bluetooth部分重要的几根线是UART、BT_REG_ON、BT_DEV_WAKE、BT_HOST_WAKE,两根WAKE脚在本系统中没有控制,直接连到低电平或悬空。

 

Bluetooth部分DTS及Kernel配置

看来我们需要配置的只有BT_RST PIN及UART,和之前一样,修改/kernel_imx/arch/arm/boot/imx6dq-sabresd.dtsi文件。

 

       BT_REG_ON在此dts文件中是作为bt_rfkill来配置的,找到相应部分,BT_RST连接到的是D17(NANDF_D3),相对应的GPIO为GPIO2_3。

    bt_rfkill {

                 compatible ="fsl,mxc_bt_rfkill";

-                        bt-power-gpios = <&gpio1 2 0>;

+                        bt-power-gpios =<&gpio2 3 0>;

                                 status="okay";

    };

 

       找到NAND中的配置,把相应PIN的配置注释掉。

 

       再看UART部分,连接到的是系统的UART3,由于Bluetooth要求有流控,所以需要配置CTS/DTS。找到pinctrl_uart3

       TX连接到F22(EIM_D24),RX连接到G22(EIM_D25),CTS连接到J20(EIM_D30),RTS连接到D15(SD3_D15)。原配置中TX/RX配置是正确的,需要更换CTS/RTS的配置。修改为:

               pinctrl_uart3: uart3grp {

                        fsl,pins = <

                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA      0x1b0b1

                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA      0x1b0b1

-                              MX6QDL_PAD_EIM_EB3__UART3_RTS_B 0x1b0b1

-                              MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1

+                               MX6QDL_PAD_SD3_RST__UART3_RTS_B 0x1b0b1

+                              MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1

                       >;

               };

 

       再修改uart3配置,增加rtscts部分。

&uart3 {

       pinctrl-names = "default";

      pinctrl-0 = <&pinctrl_uart3>;

+     fsl,uart-has-rtscts;

       status = "okay";

+       /* for DTE mode, add below change */

+       /* fsl,dte-mode; */

+       /* pinctrl-0 =<&pinctrl_uart3dte_1>; */

 };

 

       Kernel配置文件部分,打开kernel_imx/arch/arm/configs/imx_v7_android_defconfig文件看了一下,Bluetooth相关部分都是打开的,看来不需要动。

CONFIG_BT=y

CONFIG_BT_RFCOMM=y

CONFIG_BT_RFCOMM_TTY=y

CONFIG_BT_BNEP=y

CONFIG_BT_BNEP_MC_FILTER=y

CONFIG_BT_BNEP_PROTO_FILTER=y

CONFIG_BT_HIDP=y

CONFIG_BT_HCIBTUSB=y

CONFIG_BT_HCIUART=y

CONFIG_BT_HCIUART_H4=y

CONFIG_BT_HCIUART_BCSP=y

CONFIG_BT_HCIUART_ATH3K=y

CONFIG_BT_HCIBCM203X=y

 

Bluetooth串口配置文件

       编译没有出错,下载开机测试,打不开,看Log,发现以下内容:

01-01 00:37:44.221  1726  1741 I bt_vnd_conf: Attempt to load conf from/etc/bluetooth/bt_vendor.conf

01-01 00:37:44.222  1726 1741 D bt_vendor: op for 0

01-01 00:37:44.225  1726 1741 D bt_vendor: op for 0

01-01 00:37:45.730  1726 1741 D bt_hci  : start_up startingasync portion

01-01 00:37:45.730  1726 1748 I bt_hci  : event_finish_startup

01-01 00:37:45.730  1726 1748 I bt_hci_h4: hal_open

01-01 00:37:45.730  1726 1748 D bt_vendor: op for 3

01-01 00:37:45.730  1726  1748 I bt_userial_vendor: userial vendoropen: opening/dev/ttymxc4

 

       看到试图去打开的是串口ttymxc4,这是之前系统的配置,看来不是自动通过DTS文件来识别的。找到hardware/broadcom/libbt/conf/fsl/sabresd_6dq/bt_vendor.conf文件。里面果然有串口的配置,修改为:

--- a/hardware/broadcom/libbt/conf/fsl/sabresd_6dq/bt_vendor.conf

+++ b/hardware/broadcom/libbt/conf/fsl/sabresd_6dq/bt_vendor.conf

@@ -1,5 +1,5 @@

 # UART device port whereBluetooth controller is attached

-UartPort = /dev/ttymxc4

+UartPort = /dev/ttymxc2

 

 # Firmware patch filelocation

 FwPatchFilePath =/etc/firmware/bcm/

 

       另外发现一个avc权限错误。

type=1400 audit(1466056103.290:5): avc:denied { dac_override } for pid=215 comm="sh" capability=1scontext=u:r:shell:s0 tcontext=u:r:shell:s0 tclass=capability

 

       也不清楚是否和Bluetooth相关,修改了再说。

--- a/external/sepolicy/app.te

+++ b/external/sepolicy/app.te

@@ -213,7 +213,7 @@selinux_check_context(appdomain)

 

 #Superuser capabilities.

 #bluetooth requires net_admin and wake_alarm.

-neverallow { appdomain-bluetooth } self:capability *;

+#neverallow {appdomain -bluetooth } self:capability *;

 neverallow { appdomain -bluetooth }self:capability2 *;

 

--- a/external/sepolicy/shell.te

+++ b/external/sepolicy/shell.te

@@ -84,3 +84,10 @@ allow shellbootchart_data_file:file create_file_perms;

 #bugs, so we want to ensure the shell user never has this

 #capability.

 neverallow shell file_type:file link;

+

+allow shellself:capability { sys_ptrace dac_override };

 

--- a/external/sepolicy/domain.te

+++ b/external/sepolicy/domain.te

@@ -177,15 +177,15 @@ neverallow { domain-init -recovery } unlabeled:dir_file_class_set create;

 

 #Limit ability to ptrace or read sensitive /proc/pid files of processes

 #with other UIDs to these whitelisted domains.

-neverallow {

-  domain

-  -debuggold

-  -vold

-  -dumpstate

-  -system_server

-  userdebug_or_eng(`-procrank')

-  userdebug_or_eng(`-perfprofd')

-} self:capability sys_ptrace;

+#neverallow {

+#  domain

+#  -debuggold

+#  -vold

+#  -dumpstate

+#  -system_server

+#  userdebug_or_eng(`-procrank')

+#  userdebug_or_eng(`-perfprofd')

+#} self:capabilitysys_ptrace;

 

       编译重新下载后,再看Log,已经变成打开/dev/ttymcx2了。

01-01 00:37:44.221  1726  1741 I bt_vnd_conf: Attempt to load conf from/etc/bluetooth/bt_vendor.conf

01-01 00:37:44.222  1726 1741 D bt_vendor: op for 0

01-01 00:37:44.225  1726 1741 D bt_vendor: op for 0

01-01 00:37:45.730  1726 1741 D bt_hci  : start_up startingasync portion

01-01 00:37:45.730  1726 1748 I bt_hci  :event_finish_startup

01-01 00:37:45.730  1726 1748 I bt_hci_h4: hal_open

01-01 00:37:45.730  1726 1748 D bt_vendor: op for 3

01-01 00:37:45.730  1726  1748 I bt_userial_vendor: userial vendoropen: opening/dev/ttymxc2

01-01 00:14:21.100  1999 2016 E bt_hci  : startup_timer_expired

01-01 00:14:21.100  1999  2014 E bt_core_module: module_start_up failedto start up "hci_module"

01-01 00:14:21.101  1999 2023 I bt_btu  : btu_task pendingfor preload complete event

01-01 00:14:21.101  1999 2023 I bt_btu_task: Bluetooth chip preload is complete

01-0100:14:21.101  1999  2023 I bt_btu : btu_task received preload complete event             

 

古怪的CTS/RTS

       串口应该是打开了,但从Log上看,发送消息后没有回应,所以startup超时了,然后启动流程重新开始,不停的如此循环。

 

       拿示波器测量一下Bluetooth模块这边的信号,发现RX端周期性的有信号,但TX端一直是高电平,没有任何信号。又测量了RTS信号有变化,有时会低,失败后拉高。从Log上看,失败后,系统会把BT_REG_EN PIN置低再置高,所以应该是Bluetooth模块复位时把RTS拉高了,初始化完成后再置为低。CTS这个PIN一直是高电平。测量了一下BT_REG_ON这个PIN,和我们想的一增,正常拉高,如果失败了就会拉低一段时间,应该就是复位。

 

       从Kernel 的Log上可以看到下面的内容

rfkill: BT RFgoing to : off

rfkill: BT RFgoing to : on

mxc_bt_rfkill_reset

rfkill: BT RFgoing to : off

rfkill: BT RFgoing to : on

mxc_bt_rfkill_reset

 

       从UART通信协议来看,CTS为高的话,对方不允许发送,也就是说SoC不允许Bluetooth这边发送数据,所以TX没有变化。为什么CTS为一直高,太奇怪了。

 

查看Broadcom 的数据手册,Bluetooth部分的启动时序如下:

       从上图看的话,如果CTS一直为高的话,Bluetooth模块应该不会正确初始化的。查Freescale的Datasheet,关于UART口的说明也是一头雾水。分DTE和DCE两种模式。

 

       在这里,按一般理解SoC应该属于DTE设备,之后就凌乱了,开始乱试,乱配,把其它UART配置都关掉,把UART3的CTS/RTS配置反置、把UART设置为dte模式,在Bluetooth的驱动libbt/src/userial_vendor.c中把打开串口时设置为无CTS/RTS,又去找其它系统的uart部分驱动drivers/tty/serial,一通乱合并,总之是试了N种方法,但TX线就是纹丝不动。

 

 

 

       这一下了花了两天时间,想想软件没什么办法了,就考虑动硬件,把CTS脚和SoC断开,直接接地,居然也不行。后来听到有人说Freescale的串口CTS/RTS比较怪,需要CTS接CTS,RTS接RTS,和一般的系统不同。就试着把两根线互换了一下。果然通过了。

1-01 00:37:44.221  1726  1741 I bt_vnd_conf: Attempt to load conf from/etc/bluetooth/bt_vendor.conf

01-01 00:37:44.222  1726 1741 D bt_vendor: op for 0

01-01 00:37:44.225  1726 1741 D bt_vendor: op for 0

01-01 00:37:45.730  1726 1741 D bt_hci  : start_up startingasync portion

01-01 00:37:45.730  1726 1748 I bt_hci  :event_finish_startup

01-01 00:37:45.730  1726 1748 I bt_hci_h4: hal_open

01-01 00:37:45.730  1726 1748 D bt_vendor: op for 3

01-01 00:37:45.730  1726  1748 I bt_userial_vendor: userial vendoropen: opening /dev/ttymxc2

01-01 00:37:45.735  1726 1748 I bt_userial_vendor: device fd = 53 open

01-01 00:37:45.735  1726 1748 D bt_vendor: op for 1

01-01 00:37:45.760  1726 1748 I bt_hwcfg: bt vendor lib: set UART baud 3000000

01-01 00:37:45.787  1726 1748 D bt_hwcfg: Chipset BCM4335C0

01-01 00:37:45.787  1726 1748 D bt_hwcfg: Target name = [BCM4335C0]

01-01 00:37:45.787  1726 1748 I bt_hwcfg: FW patchfile: /etc/firmware/bcm/Type_ZP.hcd

01-01 00:37:46.537   228  485 W audio_hw_primary: do_out_standby... -1240931008

01-01 00:37:49.145  1726 1748 I bt_hwcfg: bt vendor lib: set UART baud 115200

01-01 00:37:49.145  1726 1748 D bt_hwcfg: Settlement delay -- 100 ms

01-01 00:37:49.145  1726 1748 I bt_hwcfg: Setting fw settlement delay to 100

01-01 00:37:49.260  1726 1748 I bt_hwcfg: bt vendor lib: set UART baud 3000000

01-01 00:37:49.260  1726 1748 I bt_hwcfg: Setting local bd addr to 22:22:FE:19:1B:62

01-01 00:37:49.286  1726 1748 I bt_hwcfg: vendor lib fwcfg completed

01-01 00:37:49.286  1726 1748 I bt_vendor: firmware callback

01-01 00:37:49.286  1726 1748 I bt_hci  :firmware_config_callback

01-01 00:37:49.293  1726 1750 I bt_btu  : btu_task pendingfor preload complete event

 

       但始终不理解,为什么会需要这么接,这种接法即不属于DCE模式,也不属于DTE模式,真不明白Freescale把一个简单的串口搞的这么复杂难懂。

 

signal11 (SIGSEGV)错误

       串口通了,在Settings->Bluetooth中试图找开Bluetooth时,很快就报错Settings出错了。看了一下Log。出现在signal 11错误。

01-0100:37:50.080  1726  1744 F libc   : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x100486 in tid 1744 (BTService Call)

01-0100:37:50.134  1726  1726 D BluetoothAdapterService:getAdapterService() - returningcom.android.bluetooth.btservice.AdapterService@620e2af

01-0100:37:50.137   532   532 D BluetoothA2dp: Proxy object connected

01-0100:37:50.140  1726  1726 D A2dpService: Received start request.Starting profile...

01-0100:37:50.155  1726  1726 I BluetoothAvrcpServiceJni:classInitNative: succeeds

01-0100:37:50.156  1726  1726 I bt_bluedroid: get_profile_interfaceavrcp

01-0100:37:50.189   226   226 I SELinux : SELinux: Loadedfile_contexts contexts from /file_contexts.

01-0100:37:50.192   226   226 F DEBUG  : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

01-0100:37:50.192   226   226 F DEBUG  : Build fingerprint:'Freescale/sabresd_6dq/sabresd_6dq:6.0.1/1.0.0-ga-rc6/20160331:eng/release-keys'

01-0100:37:50.192   226   226 F DEBUG  : Revision: '0'

01-0100:37:50.193   226   226 F DEBUG  : ABI: 'arm'

01-0100:37:50.193   226   226 F DEBUG  : pid: 1726, tid: 1744, name: BT Service Call  >>> com.android.bluetooth<<<

01-01 00:37:50.193   226  226 F DEBUG   : signal 11(SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x100486

01-0100:37:50.214   226   226 F DEBUG  :     r0 af8518c0  r1 00100486 r2 00000023  r3 00000000

01-0100:37:50.214   226   226 F DEBUG  :     r4 af8518c0  r5 9ae6723c r6 00000000  r7 00000020

01-0100:37:50.215   226   226 F DEBUG  :     r8 00000036  r9 00030367 sl 00000009  fp af85c554

01-0100:37:50.215   226   226 F DEBUG  :     ip 9b3b2e38  sp 9ae67208 lr 9b2e076f  pc b6d573ea  cpsr 20070030

01-01 00:37:50.248   226  226 F DEBUG   :

01-0100:37:50.248   226   226 F DEBUG  : backtrace:

01-0100:37:50.248   226   226 F DEBUG  :     #00 pc 000353ea  /system/lib/libc.so (strncpy+5)

01-0100:37:50.249   226   226 F DEBUG  :     #01 pc 0007976b  /system/lib/hw/bluetooth.default.so(BTA_AgRegister+78)

01-0100:37:50.249   226   226 F DEBUG  :     #02 pc 0004b9d5  /system/lib/hw/bluetooth.default.so(btif_hf_execute_service+60)

01-0100:37:50.249   226   226 F DEBUG  :     #03 pc 0003ebaf  /system/lib/hw/bluetooth.default.so(btif_in_execute_service_request+58)

01-0100:37:50.250   226   226 F DEBUG  :     #04 pc 0003fcbb  /system/lib/hw/bluetooth.default.so(btif_dm_execute_service_request+22)

01-0100:37:50.250   226   226 F DEBUG  :     #05 pc 0003c18d  /system/lib/hw/bluetooth.default.so

01-0100:37:50.250   226   226 F DEBUG  :     #06 pc 000f5639  /system/lib/hw/bluetooth.default.so

01-0100:37:50.250   226   226 F DEBUG  :     #07 pc 000f462b  /system/lib/hw/bluetooth.default.so

01-0100:37:50.250   226  226 F DEBUG   :     #08 pc 000f558b  /system/lib/hw/bluetooth.default.so

01-0100:37:50.251   226   226 F DEBUG  :     #09 pc 0003f8c3  /system/lib/libc.so(__pthread_start(void*)+30)

01-0100:37:50.251   226   226 F DEBUG  :     #10 pc 00019e55  /system/lib/libc.so (__start_thread+6)

 

SIGSEGV错误一般是非法内存访问。看了一下backtrace,找到BTA_AgRegister()函数。在文件system/bt/bta/ag/bta_ag_api.c文件中。在调用strncpy时出错。应该就是这一行了。

BCM_STRNCPY_S(p_buf->p_name[i],BTA_SERVICE_NAME_LEN+1, p_service_names[i], BTA_SERVICE_NAME_LEN);

 

       涉及到两个指针,不清楚那个出错了,应该是0x100486这个地址非法,这个地址太小了,应该不是正常的驱动或应用可能申请到的地址,把两个地址打印出来,发现是p_service_names[i]这个地址。

 

       虽然不清楚为什么会传一个非法值进来,不过可以先简单的处理一下,正确的值应该在2G以上地址。所以改为:

if ( p_service_names[i] &&(int)p_service_names[i] < 0x40000000 ) { // Address < 2G, illegal

  APPL_TRACE_ERROR ("BTA_AgRegister: service %d, %d, invalid address%x.",BTA_SERVICE_NAME_LEN,i,p_service_names[i]);

  p_buf->p_name[i][0] = 0;

} else if ( p_service_names[i] ) {

  BCM_STRNCPY_S(p_buf->p_name[i], BTA_SERVICE_NAME_LEN+1,p_service_names[i], BTA_SERVICE_NAME_LEN);

  p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;

}

else

{

  p_buf->p_name[i][0] = 0;

}

 

       重新编译下载,打开Bluetooth,不出错了,搜索到了其它设备,连接到其它设备,发送一个文件过来,接收正常。

 

修改设备名称

       在其它设备查看设备时,此设备名称为iMX6,简单,把它改为项目名称。device/fsl/sabresd_6dq/bluetooth/bdroid_buildcfg.h

 

---a/device/fsl/sabresd_6dq/bluetooth/bdroid_buildcfg.h

+++b/device/fsl/sabresd_6dq/bluetooth/bdroid_buildcfg.h

@@ -19,7 +19,7 @@

 #ifndef _BDROID_BUILDCFG_H

 #define _BDROID_BUILDCFG_H

 

-#define BTM_DEF_LOCAL_NAME"iMX6"

+#define BTM_DEF_LOCAL_NAME"Prince"

 

一些个人体会

       前后花了一个星期,移植了WiFi/BT驱动,之前没有移植过WiFi/BT驱动,所以遇到了很多问题,不过总体还算顺利。

       在Freescale平台中,WiFi的SDIO口识别是通过dts文件中增加wifi-host来区分的。

       而Bluetooth的串口是通过在bt_vendor.conf文件中配置的。

       Broadcom的驱动代码更新的比较慢,或者说比较脱节,2016年下的最新的驱动,居然默认还没有支持Android 6.0系统。移植是需要注意检查Makefile看是否加上对应平台的编译开关了。

 

待解问题

       Freescale平台的RTS/CTS始终不明白,为什么需要CTS接CTS,RTS接RTS,和一般的理解不同,不清楚是不是Bluetooth这边标错了,因为此系统中只有Bluetooth连接需要CTS/RTS,所以没法论证,以后有机会一定要确认一下。

       bt_rfkill应该是用于WiFi/BTCOEX的, 目前没有去确认一起打开时,会不会有问题,功能工作是否正常。

       WiFiWAPI部分没有加入,所以不清楚是否可用。以后有需求时还需要移植一下。