做信息安全的网站,网站建设兼职平台,建设邮箱网站,seo专员是什么职业岗位Android如果发现wifi没有正常启动#xff0c;从下面两个方面
1.是否正常编译出wifi ko文件#xff0c;如果没有#xff0c;说明编译的有问题#xff0c;ko文件的地址vendor/lib/module/devices/wifi
2.如果有编译出ko文件#xff0c;但还提示Wifi HAL start failed之类的…Android如果发现wifi没有正常启动从下面两个方面
1.是否正常编译出wifi ko文件如果没有说明编译的有问题ko文件的地址vendor/lib/module/devices/wifi
2.如果有编译出ko文件但还提示Wifi HAL start failed之类的先使用insmod手动加载ko文件查看wifi是否能正常启动如果可以说明ko文件没有成功加载如下方法查找原因 Android启动的时候会去加载wifi模块这时候这部分代码在frameworks\opt\net\wifi\libwifi_hal\这部分的代码主要的功能为大概内容为通过读取uevnt的获取到系统下的wifi模块的vip和pid从而从代码的列表中查找到是那个一个wifi模块然后又从列表中获取wifi模块的驱动代码在那里从而调用insmod xxxx.ko加载wifi模块。
frameworks\opt\net\wifi\libwifi_hal\rk_wifi_ctrl.cpp
static wifi_device supported_wifi_devices[] {{RTL8188EU, 0bda:8179},{RTL8188EU, 0bda:0179},{RTL8723BU, 0bda:b720},{RTL8723BS, 024c:b723},{RTL8822BS, 024c:b822},{RTL8723CS, 024c:b703},{RTL8723DS, 024c:d723},{RTL8188FU, 0bda:f179},{RTL8822BU, 0bda:b82c},{RTL8189ES, 024c:8179},{RTL8189FS, 024c:f179},{RTL8192DU, 0bda:8194},{RTL8812AU, 0bda:8812},{SSV6051, 3030:3030},{ESP8089, 6666:1111},{AP6354, 02d0:4354},{AP6330, 02d0:4330},{AP6356S, 02d0:4356},{AP6335, 02d0:4335},{AP6255, 02d0:a9bf},{RTL8822BE, 10ec:b822},{MVL88W8977, 02df:9145},
};frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cpp//wifi模块的驱动ko,文件的路径地址/vendor/lib/modules/
#define WIFI_MODULE_PATH /vendor/lib/modules/
wifi_ko_file_name module_list[]
{{RTL8723BU, RTL8723BU_DRIVER_MODULE_NAME, RTL8723BU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8188EU, RTL8188EU_DRIVER_MODULE_NAME, RTL8188EU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8192DU, RTL8192DU_DRIVER_MODULE_NAME, RTL8192DU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8822BU, RTL8822BU_DRIVER_MODULE_NAME, RTL8822BU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8822BS, RTL8822BS_DRIVER_MODULE_NAME, RTL8822BS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8188FU, RTL8188FU_DRIVER_MODULE_NAME, RTL8188FU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8189ES, RTL8189ES_DRIVER_MODULE_NAME, RTL8189ES_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8723BS, RTL8723BS_DRIVER_MODULE_NAME, RTL8723BS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8723CS, RTL8723CS_DRIVER_MODULE_NAME, RTL8723CS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8723DS, RTL8723DS_DRIVER_MODULE_NAME, RTL8723DS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8812AU, RTL8812AU_DRIVER_MODULE_NAME, RTL8812AU_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8189FS, RTL8189FS_DRIVER_MODULE_NAME, RTL8189FS_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{RTL8822BE, RTL8822BE_DRIVER_MODULE_NAME, RTL8822BE_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{SSV6051, SSV6051_DRIVER_MODULE_NAME, SSV6051_DRIVER_MODULE_PATH, SSV6051_DRIVER_MODULE_ARG},{ESP8089, ESP8089_DRIVER_MODULE_NAME, ESP8089_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{AP6335, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{AP6330, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{AP6354, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{AP6356S, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{AP6255, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{APXXX, BCM_DRIVER_MODULE_NAME, BCM_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{MVL88W8977, MVL_DRIVER_MODULE_NAME, MVL_DRIVER_MODULE_PATH, MVL88W8977_DRIVER_MODULE_ARG},{RK912, RK912_DRIVER_MODULE_NAME, RK912_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},{UNKNOW, DRIVER_MODULE_NAME_UNKNOW, DRIVER_MODULE_PATH_UNKNOW, UNKKOWN_DRIVER_MODULE_ARG}};
hardware\interfaces\wifi\1.2\default\service.cpp
//加载 WifiModeController然后会调用到WifiModeController::WifiModeController()
android::spandroid::hardware::wifi::V1_2::IWifi service new android::hardware::wifi::V1_2::implementation::Wifi(std::make_sharedWifiLegacyHal(),std::make_sharedWifiModeController(), std::make_sharedWifiFeatureFlags());hardware\interfaces\wifi\1.2\default\wifi_mode_controller.cpp
WifiModeController::WifiModeController() : driver_tool_(new DriverTool) {}bool WifiModeController::initialize() {if (!driver_tool_-LoadDriver()) { //调用到下面的 LoadDriverLOG(ERROR) Failed to load WiFi driver;return false;}return true;
}加载wifi驱动代码调用路径
frameworks\opt\net\wifi\libwifi_hal\driver_tool.cppbool DriverTool::LoadDriver()return ::wifi_load_driver()wifi_load_driver() //frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cppcheck_wifi_chip_type_string //frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cppif (!strcmp(wifi_type , module_list[i].wifi_name)) {wifi_ko_path module_list[i].wifi_module_path; //从module_list中获取到wifi驱动xxxx.ko的路径在这里是/vendor/lib/modules/xxxx.ko wifi_ko_arg module_list[i].wifi_module_arg;}save_wifi_chip_type(wifi_type); //保存我们加载wifi的一些信息这些信息用来给wpa_supplicant加载对于的wifi启动参数。insmod(wifi_ko_path, wifi_ko_arg) //加载ko模块和我们手动命令insmod xxxx.ko效果一样的//此功能为了从supported_wifi_devices这个列表里面获取当前SDIO上面挂载的是那个模块
int check_wifi_chip_type_string(char *type)
{if (identify_sucess -1) {if (get_wifi_device_id(SDIO_DIR, PREFIX_SDIO) 0)PLOG(DEBUG) SDIO WIFI identify sucess;else if (get_wifi_device_id(USB_DIR, PREFIX_USB) 0)PLOG(DEBUG) USB WIFI identify sucess;else if (get_wifi_device_id(PCIE_DIR, PREFIX_PCIE) 0)PLOG(DEBUG) PCIE WIFI identify sucess;else {PLOG(DEBUG) maybe there is no usb wifi or sdio or pcie wifi,set default wifi module Brocom APXXX;strcpy(recoginze_wifi_chip, APXXX);identify_sucess 1 ;}}strcpy(type, recoginze_wifi_chip); //复制supported_wifi_devices里面的wifi_name的值PLOG(ERROR) check_wifi_chip_type_string : type;return 0;
}
wifi启动驱动加载fw流程 现在的wifi模块启动的时候都要加载一个fw固件这个固件是做什么用的呢可能是厂商用来做一下差异配置把或者是加载射频参数进行使用大家可以理解为加载一个bin文件到wifi模组中每次wiif模组上电的时候都需要加载一次加载的操作在wifi驱动的加载的时候不同的厂商加载的bin文件不一样下面我们可以通过系统启动的时候打印的log可以看到如下打印下面的例子是博通的wifi模组的打印Realtek不一样
博通wifi加载过程 Final fw_path/vendor/etc/firmware/fw_bcm43438a1.bin
[ 64.276445] Final nv_path/vendor/etc/firmware/nvram_ap6212a.txt
[ 64.276669] Final clm_path/vendor/etc/firmware/clm.blob
[ 64.276896] Final conf_path/vendor/etc/firmware/config.txt
[ 64.279224] dhd_os_open_image: /vendor/etc/firmware/fw_bcm43438a1.bin (414665 bytes) open success
[ 64.365150] dhd_os_open_image: /vendor/etc/firmware/nvram_ap6212a.txt (1003 bytes) open success
[ 64.365249] NVRAM version: AP6212A_NVRAM_V1.0.1_20160606grep Final fw_path -nr
通过查找Final fw_path查找出在那里打印出的log从而找到。
kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c:8341: printf(Final fw_path%s\n, bus-fw_path);
所以可以知道在驱动里面会加载fw固件但是这个固件的地址是在那里传进来的需要进一步追踪bus-fw_path这个值。
经过追踪发现在rockchip这个平台固件的路径在内核里面写死了代码在kernel\drivers\net\wireless\rockchip_wlan\rkwifi\rk_wifi_config.c里面定义了一个函数int rkwifi_set_firmware(char *fw, char *nvram)这个函数在博通的wifi驱动里面被调用从而获取wifi固件的烧录地址kernel\drivers\net\wireless\rockchip_wlan\rkwifi\bcmdhd\dhd_linux.c的bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)中被调用。
对于博通的wifi和蓝牙二和一芯片来说一般需要加载3个固件分别对应给wifi和蓝牙使用的 对于wifi部分有fw_bcm43438a1.bin和nvram_ap6212a.txt 对于蓝牙部分的固件有 bcm43438a1.hcd
对于Realtek的wifiwifi部分不需要加载固件但是蓝牙需要加载固件固件的地址在kernel\drivers\bluetooth\rtk_btusb.c里面定义
static patch_info fw_patch_table[] {
/* { vid, pid, lmp_sub_default, lmp_sub, everion, mp_fw_name, fw_name, config_name, fw_cache, fw_len, mac_offset } */
{ 0x0BDA, 0x1724, 0x1200, 0, 0, mp_rtl8723a_fw, rtl8723a_fw, rtl8723a_config, NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723A */
{ 0x0BDA, 0x8723, 0x1200, 0, 0, mp_rtl8723a_fw, rtl8723a_fw, rtl8723a_config, NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE */
{ 0x0BDA, 0xA723, 0x1200, 0, 0, mp_rtl8723a_fw, rtl8723a_fw, rtl8723a_config, NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE for LI */
{ 0x0BDA, 0x0723, 0x1200, 0, 0, mp_rtl8723a_fw, rtl8723a_fw, rtl8723a_config, NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE */
{ 0x13D3, 0x3394, 0x1200, 0, 0, mp_rtl8723a_fw, rtl8723a_fw, rtl8723a_config, NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE for Azurewave*/
蓝牙加载驱动的时候内核层会调用request_firmware(cfg, config_name, udev-dev);来下载固件。 request_firmware使用方法可以参考https://blog.csdn.net/magod/article/details/6049558。 当内核调用request_firmware这个函数的时候在应用层就会在这个目录/sys/class/firmware生成一个节点这个节点由三个属性分为为
loading
这个属性应当被加载固件的用户空间进程设置为 1. 当加载进程完成, 它应当设为 0. 写一个值 -1 到 loading 会中止固件加载进程.data
data 是一个二进制的接收固件数据自身的属性. 在设置 loading 后, 用户空间进程应当写固件到这个属性.device
这个属性是一个符号连接到 /sys/devices 下面的被关联入口项.所有由此推测需要下载蓝牙固件的时候应用层一定会往data这个属性写入固件的数据。
android hal 加载wpa_supplicant流程 我们前面的《android hal 加载wifi ko模块流程》中已经说明了系统启动后会获取到 wifi 芯片 vid pid 加载相应的wifi ko驱动然后在加载ko驱动的同时保存wifi芯片的一些信息比如我们加载的wifi模块是博通Broadcom的就保存好博通Broadcom wifi的名字等信息如果是加载的模块是瑞昱Realtek的就保存瑞昱Realtekwifi名字的信息。之后系统会启动之后系统会读取init.connectivity.rc 这个脚本这个脚本会启动wpa_supplicant这个服务这个应用服务会常驻在后台启动wpa_supplicant的时候需要指定wifi模块的参数参数保存在“/vendor/etc/wifi/wpa_config.txt”源码目录放在/device/rockchip/common/wpa_config.txt。
librkwifi-ctrl.so从那里来 在\frameworks\opt\net\wifi\libwifi_hal\Android.bp
cc_library_shared { //编译成可执行文件cc_library_shared编译成动态库name: librkwifi-ctrl, //生成librkwifi-ctrl.so库vendor: true, //编译出来放在/vendor目录下(默认是放在/system目录下)cflags: wifi_hal_cflags,local_include_dirs: [include], //用户值定的头文件查找路径shared_libs: [libbase], //编译依赖的动态库 header_libs: [libcutils_headers],srcs: [rk_wifi_ctrl.cpp], //源文件格式[a.cpp, b.cpp]
}