Android 驱动库的动态加载

Android系统通常会添加一些外设,而外设也分为很多厂商,为了自适应不同厂商Android需要动态加载这些外设的驱动,那么在hardware模块做好兼容工作。

通常HAL层动的较多的就是蓝牙和wifi模块,HAL层在蓝牙,wifi的系统服务的控制下操作驱动模块,例如wpa_supplicant, wpa_cli, bluedroid, 等服务,存在于

external/bluetooth/bluedroid, external/wpa_supplicant_8,packages/apps/Bluetooth,frameworks/opt/net/wifi等目录下。


确定芯片ID

wifi芯片模块连接后,通过USB总线可以查到对应芯片的ID。一般在插上usb Dangle设备后,在/dev/bus/usb/ 目录下会有001,  002 ,003 子目录,HAL层可以

读取到vendor ID , product ID ,得到这些ID 之后就可以匹配对应的厂商驱动,例如wifi可以查看配置文件wifi.cfg

(1)lsusb 可以查看芯片ID

130|shell@cv6a638_base:/ # busybox lsusb                                       
Bus 002 Device 002: ID 8644:800e
Bus 003 Device 002: ID 0bda:b720
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0002
Bus 003 Device 001: ID 1d6b:0002
(2)wifi.cfg配置vid pid

=====
wifi_vendor_name=RTL8192EU
order=1
count_vid_pid=1
vid_pid=0x0bda:0x818b
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=ATH9375
order=2
count_vid_pid=3
vid_pid=0x0cf3:0x1022
vid_pid=0x0cf3:0x1023
vid_pid=0x0cf3:0x9375
sta=1
softap=0
p2p=1
=====
wifi_vendor_name=MT7662STA
order=3
count_vid_pid=2
vid_pid=0x0e8d:0x7632
vid_pid=0x0e8d:0x7662
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=MT7603STA
order=4
count_vid_pid=1
vid_pid=0x0e8d:0x7603
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=RAL5370
order=5
count_vid_pid=4
vid_pid=0x148f:0x5370
vid_pid=0x148f:0x5372
vid_pid=0x148f:0x3070
vid_pid=0x148f:0x5572
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=RTL8188ETV
order=6
count_vid_pid=2
vid_pid=0x0bda:0x0179
vid_pid=0x0bda:0x8179
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=RTL8812AUS
order=7
count_vid_pid=2
vid_pid=0x0bda:0x8812
vid_pid=0x0bda:0x881a
sta=1
softap=1
p2p=1
=====
wifi_vendor_name=RTL8723BU
order=8
count_vid_pid=1
vid_pid=0x0bda:0xb720
sta=1
softap=1
p2p=1

确定芯片类型

 根据上面lsusb 信息以及wifi.cfg里面的配置信息得知芯片类型为; RTL8723BU


动态加载驱动

HAL层wifif.c 文件中,函数wifi_common_load_driver利用 ctl.start  属性来加载init.*.rc中配置的服务

    //property_set(DRIVER_PROP_NAME,"");
    sched_yield();
    property_set("ctl.start", daemon_cmd);
此处daemon_cmd 为加载驱动的命令,也即是启动一个脚本,输入驱动类型,赋值如下:

snprintf(daemon_cmd,sizeof(daemon_cmd),"loadwifi:%s",wlan_driver);

启动脚本添加服务

从上面步骤可以看到,是启动loadwifi服务,那么这个wifiload服务在哪里注册?

我们可以查看init.*.rc 启动脚本中的loadwifi服务

service loadwifi /system/bin/wifi_load_driver.sh
    class main                                  
    disabled                                
    oneshot                        
    seclabel u:r:loadwifi:s0
其实服务就是启动了一个脚本


驱动加载配置

最后,我们再看看加载在哪里配置,wifi_load_driver.sh

#!/system/bin/sh

echo "wifi_load_driver $1"
case $1 in
RTKM)
insmod /system/lib/modules/rtkm.ko
;;
MTKM)
insmod /system/lib/modules/mtprealloc.ko
;;
RAL5370)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/firmware_class.ko
insmod /system/lib/modules/rt5572sta.ko
sleep 1
;;
RTL8723BU)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8723bu.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
RTL8192CU)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8192cu.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
RTL8192DU)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8192du.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
RTL8192EU)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8192eu.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
ATH1021)
insmod /system/lib/modules/compat.ko
insmod /system/lib/modules/cfg80211_ath6k.ko
insmod /system/lib/modules/ath6kl_usb.ko chip_pwd_l=0 ht40_24ghz=1 htcoex=1 ath6kl_p2p=1
iw dev wlan0 interface add p2p0 type managed
sleep 1
;;
RTL8812AUS)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8812au.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
RTL8188ETV)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8188eu.ko ifname=wlan0 if2name=p2p0
sleep 1
;;
RTL8712U)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/8712u.ko
sleep 1
;;
ATH9375)
insmod /system/lib/modules/compat_9375.ko
insmod /system/lib/modules/cfg80211_ath6k_9375.ko
insmod /system/lib/modules/ath6kl_usb_9375.ko ath6kl_p2p=0x19 debug_quirks=0x200
iw dev wlan0 interface add p2p0 type managed
sleep 1
;;
ATH9374)
insmod /system/lib/modules/widi/compat_9374.ko
insmod /system/lib/modules/widi/cfg80211_ath6k_9374.ko
insmod /system/lib/modules/widi/ath6kl_usb_9374.ko chip_pwd_l=0 ht40_24ghz=1 htcoex=1 ath6kl_p2p=1
iw dev wlan0 interface add p2p0 type managed
sleep 1
;;
MT7662STA)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/firmware_class.ko
insmod /system/lib/modules/mt7662u_sta.ko
sleep 2
;;
MT7603STA)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/firmware_class.ko
insmod /system/lib/modules/mt7603u_sta.ko
sleep 1
;;
MT7601STA)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/mt7601Usta.ko
sleep 1
;;
BCM43438)
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/bcmdhd.ko "firmware_path=/system/etc/wifi/fw_bcm43438a0.bin nvram_path=/system/etc/wifi/nvram_ap6212.txt"
sleep 1
;;
BCM43569)
bcmdl -n /system/etc/wifi/nv_bcm43569.txt /system/etc/wifi/fw_bcm43569a2.bin
insmod /system/lib/modules/cfg80211.ko
insmod /system/lib/modules/bcmdhd_43569.ko
sleep 1
;;
*)
echo "no driver!!!"
;;
esac

在此处我们可以看到,驱动RTL8723BU的加载,至此整个动态加载流程完毕,另外动态卸载也可以,对应新增的驱动可以采取这种框架来添加其他外设驱动非常方便。


另外ctrl.start 系统属性可以参考 http://www.cnblogs.com/bastard/archive/2012/10/11/2720314.html








你可能感兴趣的:(android)