分类: LINUX
2012-01-30 14:36:24
The Android kernel uses a TI-provided 802.11 driver. This driver is GPLed, however it does not use the standard Linux wireless stack. Kalle Valo of Nokia has written a mac80211-based driver, wl12xx, which was mainlined in 2.6.31, and I have written the SDIO interface logic, likely to go in for 2.6.32.
Most people should just stick with the driver that comes with the ADP1, as it’s rather painful to switch drivers and there are few benefits to using wl12xx at this time. However, in the interest of having a mainlined wifi driver on the device, here are a few notes on how to install and use wl12xx.
There is a lot of room for streamlining the process here, but this is more or less what I’ve arrived at. Please let me know if there are any errors.
I assume you already have ADP v1.5 installed since the kernel needs a recent userspace. I also have busybox installed in my path, but I’ve left out any manual path setup for brevity’s sake.
These patches are also linked inline:
Android uses a wpa_supplicant build with a custom driver for the TI vendor driver. The UI communicates with this lower level via the Java class android.net.wifi.WifiNative, which is implemented in android_net_wifi_Wifi.cpp. This, in turn, uses functions in libhardware_legacy/wifi/wifi.c to interact with the wpa_supplicant control socket located on the device in /dev/socket/wpa_tiwlan0. Android handles some additional commands not included in the stock wpa_supplicant, defined in external/wpa_supplicant/ctrl_iface.c.
Note, the default wpa_supplicant drivers (e.g. -Dwext), will not do anything useful for the custom Android commands, so the UI will not work properly at this time. My patch for wpa_supplicant adds a few stubs to the nl80211 driver, but it is incomplete.
The Android code drop described here includes a kernel tree as well as a cross-compiler toolchain and userland. You will need to build this first to create all the libraries for building userspace utilities.
I prefer to clone my kernel directly rather than using the repo tool, Also I use the 2.6.29 version because it is compatible with compat-wireless, and the precompiled tiwlan driver won’t load so it doesn’t get in the way.
Apply to create a new module called msm_wifi. This module sets GPIOs appropriately to power up the wifi module and implement virtual card-select; it needs to be loaded for wl1251_sdio to successfully probe the device.
You should configure the kernel with at least SDIO and MAC80211 support (). Put the arm toolchain in your path and do:
Current compat-wireless contains everything you need to build wl1251_sdio. Download it .
I use a short script to take care of cross-compiling compat-wireless:
Once built, I use the following script to copy the modules to the device:
Also, a script on the phone itself makes it easy to load everything without setting up modules.dep properly:
wl12xx needs two firmware files. One includes the standard firmware which is the same for all devices, and another that includes calibration data that is specific to each individual device. To get them in the right place, boot the normal kernel. Turn on the wifi to load the TI driver, then do:
In my opinion, the easiest way to load a custom kernel is to unpack the ramdisk image from the 1.5 firmare package, then boot with the self-compiled zImage. To get the ramdisk, I use the script on the boot.img from the Android 1.5 system image zip archive:
To boot the kernel, put the phone in fastboot mode. Plug the phone into USB, then hold down the back-arrow while turning the phone on. This should bring up the boot loader (robots on skateboards) with the string "FASTBOOT" in the center. Now run the fastboot tool:
You won’t see anything for a minute or so, then the phone will reboot. If you have all the proper tools installed (see below) and a wpa_supplicant.conf, you can then try loading the modules and associating:
If all goes well, wlan0 will have associated with your AP and you’re up and running.
You can rebuild the wpa_supplicant that comes with the Android build environment to also support wl1251 (and any other mac80211 driver) by including the wireless extensions driver. To do so, from the toplevel Android directory, edit external/wpa_supplicant/Makefile and add the following lines to the mkconfig target:
Then build the supplicant:
However, WEXT is old and busted and NL80211 is the new hotness, so read on to build one that supports nl80211.
Here’s how to build a recent, dynamically-linked wpa_supplicant from git. Note it does not include support for the tiwlan0 driver that works with the vendor driver. The SHA-1s noted below are known to work but newer ones might also suffice.
Grab the tree for libnl:
Then apply . Be sure to edit lib/Makefile and change ANDROID to point to your android build environment.
Hopefully, make completed successfully and spat out libnl.so. If not, good luck figuring it out. Wrestling with the include order to satisfy the cross compiler and bionic libc is "fun."
This needs to go into the /system/lib/ directory on the device because the library search path is hard-coded. You can use the mount -o remount,rw trick to get it there from the sdcard.
Now get wpa_supplicant (part of hostap package):
Then apply . Again, edit wpa_supplicant/config_android to configure the ANDROID and LIBNL paths appropriately.
You now have a wpa_supplicant binary dynamically linked against bionic libc and libnl.so. Unlike the android fork, it does not include the custom TI supplicant driver, so it can only be used with wl12xx or other native Linux drivers.
Either version of wpa_supplicant needs a config file like the following to connect to your AP:
iw is an iwconfig replacement using netlink. You must first build and install libnl.so as above.
Then apply . Once more, edit the Makefile for ANDROID and LIBNL, then do: