Freescale i.MX 6 MNC平臺移植BT/WIFI驅動
此專案之前移植到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:[email protected] {
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() - [email protected]
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部分沒有加入,所以不清楚是否可用。以後有需求時還需要移植一下。