강좌 & 팁
이번에 s5pv210 안드로이드에 Marvell sd8787 wlan모듈을 기존 리눅스 방식대로 올려보았습니다.
일단 커널 콘솔모드에서만 동작하도록 하는 것이 목표였기 때문에 기존 리눅스 방식대로 따라했습니다.
맨처럼 sd8787 무선랜 모듈 드라이버를 빌드해서 .ko를 생성합니다.
반드시 커널 오브젝트 파일들이 있는 빌드 디렉토리를 알아야하기 때문에 해당 안드로이드 커널 소스도 준비해야합니다.
그리고 반드시 kernel menuconfig에서 아래와 같이 IEEE 802.11 Host AP 및 Marvell Libertas support를 활성화 시켜서 빌드합니다.
$ ./make-s5pv210.sh menuconfig
Device Drivers ---> [*] Network device support ---> [*] Wireless LAN --->
<*> Marvell 8xxx Libertas WLAN driver support with thin firmware
<*> IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)
<*> Marvell 8xxx Libertas WLAN driver support
해당 메뉴가 나오지 않으면 아래의 경로에서 옵션을 추가한 후 그 위치로 가보시면 메뉴가 세로 생성되어 있습니다.
[*] Networking support ---> -*- Wireless --->
<*> cfg80211 - wireless configuration API
[*] cfg80211 regulatory debugging
[*] enable powersave by default
[*] cfg80211 wireless extensions compatibility
[*] Wireless extensions sysfs files
-*- Common routines for IEEE802.11 drivers
<*> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Minstrel
드라이버 소스 디렉토리의 Makefile을 열기한 후 다음과 같이 수정합니다. Makefile은 소스(src/)디렉토리에 있습니다.
아래처럼 방금 위에서 수행했던 커널의 빌드 디렉토리를 지정합니다.
root@xxx:src#vi Makefile
KERNELDIR ?=../../../../../../kernel/build_linux-2.6.35.14
그리고 툴체인도 안드로이드 커널을 빌드했던 동일한 CodeSourcery 툴체인을 지정합니다.
CROSS_COMPILE ?= arm-none-eabi-
이제 빌드를 합니다. 빌드는 반드시 root 계정으로 합니다. root가 아니면 빌드가 되지 않습니다.
소스 디렉토리에서 간단히 make만 하면 빌드가 됩니다. 그전에 clean을 한번 하고 make하는 것이 좋습니다.
root@xxx:src# make clean
root@xxx:src# make
끝나고 나면 아래와 같이 2개의 모듈이 생겼다는 메시지가 표시됩니다. 그리고 ls -al해보면 mlan.ko와 sd8787.ko파일이
생성되어 있습니다.
.............
Building modules, stage 2.
MODPOST 2 modules
CC /driver-sdio-wlan-AW_NH387L/src/mlan.mod.o
LD [M] /driver-sdio-wlan-AW_NH387L/src/mlan.ko
CC /driver-sdio-wlan-AW_NH387L/src/sd8787.mod.o
LD [M] /driver-sdio-wlan-AW_NH387L/src/sd8787.ko
그런데 안드로이드 파일시스템이 기존 리눅스와 달라서 모듈 위치와 hotplug 펌웨어 위치를 찾는것이 애매했습니다.
모듈들은 nfs로 mount해서 설치해도 되지만 펌웨어 바이너리는 특정디렉토리에 넣어야 찾아서 다운로드되고 무선랜 장치가 active 됩니다.
이래저래 찾아보니 안드로이드에서는 .ko 모듈들을 /system/lib/modules 아래에 넣고
hotplug 펌웨어는 보통 /system/etc/firmware 디렉토리에 위치합니다.
커널마다 다르긴 한데 /system 디렉토리 밑에 firmware라는 디렉토리가 있으면 거기에 무선랜의 펌웨어를 올리면 됩니다.
저같은 경우는 이더넷을 이용해서 nfs를 mount해서 아래와 같은 경로에 모듈과 펌웨어를 넣었습니다.
안드로이드 콘솔에서 busybox를 이용해서 ifconfig로 유선랜을 활성화하고 mount로 nfs를 마운트합니다.
그전에 su로 root 계정으로 만들어야 합니다. 자동완성이 되지 않기 때문에 tab을 누리지 않도록 합니다..^^:;;;
$ su
sh: can't access tty; job control turned off
# busybox ifconfig eth0 192.168.1.10
# busybox mount -t nfs -o nolock 192.168.1.2:/nfs /mnt/nfs
# cd /mnt/nfs
# ls
mlan.ko
sd8787.ko
sd8787_uapsta.bin
sd8787_uapsta_w1.bin
#busybox cp -a *.bin /system/etc/firmware/mrvl
#busybox cp -a *.ko /system/modules
이렇게 한 후에 insmod로 모듈을 설치합니다.
# cd /system/modules
# insmod mlan.ko
# insmod sd8787.ko
[ 330.542032] WLAN FW is active
#
이렇게 나오면 정상적으로 펌웨어가 다운로드 되어서 모듈이 활성화 되었고 iwconfig로 확인 가능합니다.
# iwconfig
lo no wireless extensions.
eth0 no wireless extensions.
ifb0 no wireless extensions.
ifb1 no wireless extensions.
usb0 no wireless extensions.
sit0 no wireless extensions.
ip6tnl0 no wireless extensions.
mlan0 IEEE 802.11-DS ESSID:"" Nickname:""
Mode:Managed Access Point: Not-Associated Bit Rate:1 Mb/s
Tx-Power=8 dBm
Retry limit:9 RTS thr=2347 B Fragment thr=2346 B
Encryption key:off
Power Management:on
Link Quality=0/5 Signal level=0 dBm Noise level=0 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:1
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
uap0 IEEE 802.11-DS ESSID:""
Mode:Master Frequency:2.437 GHz Access Point: Not-Associated
Encryption key:off
Link Quality:0 Signal level:0 Noise level:0
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0
#
이렇게 해서 무선랜을 AP와 붙이기 위해서는 리눅스와 마찬가지로 wireless tools를 사용하시면 됩니다.
아래는 WPA 방식으로 AP와 연결하기 위한 예입니다.
# iwpriv mlan0 passphrase "1;passphrase=12345abcd"
# iwconfig mlan0 essid "mlan_ap"
# ifconfig mlan0 192.xxx.xxx.xxx 또는 udhcpc -I mlan0
아니면 안드로이드에 기본 내장된 wpa_supplicant를 이용해서 연결할수도 있습니다. 이 경우 etc/wifi/wpa_supplicant.conf파일을 수정해서 적용합니다. 마찬가지로 WPA/TKIP 방식으로 AP와 연결합니다. 아무래도 WPA로 접속할 경우 wpa_supplicant가 더욱 편할 것 같습니다.
##### wpa_supplicant configuration file template #####
network={
ssid="mlan_ap"
proto=WPA
key_mgmt=WPA-PSK
pairwise=TKIP
group=TKIP
psk="12345abcd"
}