본문 바로가기

임베디드

USB 무선랜 드라이버 구동

Mediatek사의 RT5370칩셋이 장착된 USB 무선랜 장치(모듈)는 구하기도 쉽고 가격도 매우 저렴하다.

실제 알리익스프레스에서 $2~$3의 초저가에 무료배송으로 구입할 수 있으니 여유있게 몇개 주문해 놓자.

안테나가 내장된 소형 모듈은 보통 아래와 같은 구조로 되어 있다.

 

 

 

 

 

원래 Ralink사에서 만든 칩이지만 2011년에 Ralink는 MediaTek 인수되었다.

시시콜콜한 반도체 회사들의 M&A 이야기를 하는 이유는 디바이스 드라이버의 설명이 Ralink 로 되어 있기 때문이다.

이 무선랜 칩이 사용할 디바이스 드리이버의 이름은 RT2X00이다.

 

 

 

무선랜 관련 드라이버는 Built-in으로 설정하면 정상동작하지 않는다. 무선랜 칩셋이 필요로하는 바이너리 펌웨어 파일이 루트파일 시스템에 존재하는데, 커널 부팅이 끝날때까지 루트파일 시스템은 아직 마운트가 안되어 필요한 펌웨어 파일을 로딩할 수 없기 때문이다. 물론 램디스크를 이용해서 커널이 부팅될때 펌웨어 파일에 접근할 수 있도록 만들면 가능은 하지만 시스템 가용 메모리가 아주 작은 i3/S3 플랫폼에서는 바람직한 방법은 아닌것 같다.

따라서 RT2X00 디바이스 드라이버는 아래와 같이 Module로 설정한다.

 

 

커널을 컴파일하면 rt2x00lib , rt2800lib, rt2x00usb, rt2800usb 이렇게 4개의 커널 모듈 .ko 파일이 생성된다.

우선 테스트를 위해 4개 파일을 rootfs에 복사를 하고 아래의 순서로 드라이버 모듈을 로딩한다.

  insmod rt2x00lib.ko
  insmod rt2800lib.ko 
  insmod rt2x00usb.ko 
  insmod rt2800usb.ko 

그리고 nmcli 명령으로 AP에 접속하고 통신 테스트를 해본다.

 

아래 명령어는 순서대로 주변에 있는 AP들의 목록을 가져온고, 알고 있는 AP의 비번으로 접속하고, 할당받은 IP 주소 확인하고, ping 명령으로 인터넷 연결까지 확인해본 것이다.

# root@bionic-minimal:~# nmcli device wifi list
.
.
.
.
.


# nmcli device wifi connect "My_home_2.4G" password "mypassword"

Device 'wlx7cdd90a9d2d2' successfully activated with 'eebfd397-ecbb-477f-b9ae-55350fde9500'.

# nmcli device
DEVICE           TYPE      STATE      CONNECTION          
wlx7cdd90a9d2d2  wifi      connected  Hardkernel Lab 2.4G 
eth0             ethernet  unmanaged  --                  
lo               loopback  unmanaged  --                  

# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 02:01:05:56:2f:75 brd ff:ff:ff:ff:ff:ff
3: wlx7cdd90a9d2d2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 7c:dd:90:a9:d2:d2 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.167/24 brd 192.168.10.255 scope global dynamic noprefixroute wlx7cdd90a9d2d2
       valid_lft 3068931652sec preferred_lft 3068931652sec

# ping google.com
PING google.com (216.58.220.206) 56(84) bytes of data.
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=1 ttl=49 time=53.0 ms
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=2 ttl=49 time=57.6 ms
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=3 ttl=49 time=52.5 ms
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=4 ttl=49 time=78.2 ms
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=5 ttl=49 time=56.2 ms
64 bytes from del01s08-in-f206.1e100.net (216.58.220.206): icmp_seq=6 ttl=49 time=54.7 ms
^C
--- google.com ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5008ms
rtt min/avg/max/mdev = 52.519/58.755/78.229/8.883 ms

 

USB 무선랜의 기본 동작은 모두 확인하였으나 좀 더 다듬을 필요가 있다.

컴파일된 모듈은 원래 modules라는 폴더에 modprobe dependancy 관리용 파일들과 함께 설치하여야 한다.

그래야만 무선랜 동글이 검출되는 순간 udev 데몬과 연동하여 관련 모듈들이 자동으로 로딩되도록 만들어야 하기 때문이다.

 

커널 소스 디렉터리의 루트에서 아래와 같은 순서로 모듈을 빌드해 보자. 

mkdir my_modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install INSTALL_MOD_PATH=my_modules

빌드한 모듈들은 my_modules 폴더에 아래와 같은 구조로 저장된다. 

 

 

이를 타겟 보드용 부팅 장치의 /lib 디렉토리에 복사하면 된다.

build와 source 폴더는 복사하지 않아도 USB 무선랜의 동작에는 문제를 일으키지 않는데, 이유는 타겟 보드에서 커널 관련 소스를 직접 컴파일할때 참조하는 용도로만 사용되기 때문이다.

 

그래서 build와 source 소프트링크를 지우고 SD카드에 복사하였다.

rm my_modules/lib/modules/5.5.0-rc4-00010-g6caee30eaa3a/source
rm my_modules/lib/modules/5.5.0-rc4-00010-g6caee30eaa3a/build
sudo cp -r my_modules/lib/ /media/dev_host/rootfs/.

보드를 다시 켜보면 수동으로 module을 올리거나 nmcli 명령어 설정하는 과정없이 바로 무선랜으로 인터넷 접속이 가능한 것을 확인할 수 있다.

 

커널 로그에 무선랜 장치가 검출되고 자동으로 칩셋용 드라이버와 펌웨어 파일이 로딩되어 시스템 네트웍 장치로 등록하는 과정이 보인다.

[    8.639252] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5390, rev 0502 detected
[    8.762630] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 5370 detected
[    8.763432] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[    8.764795] usbcore: registered new interface driver rt2800usb
[   12.136559] rt2800usb 1-1.2:1.0 wlx7cdd90a9d2d2: renamed from wlan0
[   21.780191] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
[   21.815244] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.36
[   26.320779] wlx7cdd90a9d2d2: authenticate with 90:9f:33:ba:37:02
[   26.352212] wlx7cdd90a9d2d2: send auth to 90:9f:33:ba:37:02 (try 1/3)
[   26.356328] wlx7cdd90a9d2d2: authenticated
[   26.360222] wlx7cdd90a9d2d2: associate with 90:9f:33:ba:37:02 (try 1/3)
[   26.364190] wlx7cdd90a9d2d2: RX AssocResp from 90:9f:33:ba:37:02 (capab=0x411 status=0 aid=5)
[   26.376198] wlx7cdd90a9d2d2: associated

 

RT5370은 2.4Ghz 대역만 지원하는 무선랜 칩이다. 좀 더 좋은 RT5572칩이 장착된 USB 무선랜 장치를 연결해 보았다.

5Ghz 대역의 AP와 문제없이 접속되는 것을 확인하였다.

# nmcli device wifi connect "My_Home_5G" password "my_password"
Device 'wlx7cdd908691bf' successfully activated with 'f6b4f797-71a6-48d3-a5eb-89e4769ce335'.
# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=49 time=47.2 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=49 time=46.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=49 time=47.4 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=49 time=46.9 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=49 time=47.2 ms
64 bytes from 8.8.8.8: icmp_seq=6 ttl=49 time=46.9 ms
64 bytes from 8.8.8.8: icmp_seq=7 ttl=49 time=47.0 ms
64 bytes from 8.8.8.8: icmp_seq=8 ttl=49 time=47.1 ms
^C
--- 8.8.8.8 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 7009ms
rtt min/avg/max/mdev = 46.920/47.123/47.439/0.249 ms

 

Kernel defconf 파일의 변경 내용은 아래 comit ID를 통해 확인 가능하다. 

https://github.com/foxnux/linux/commit/b8522136326fe205c2be9a46282e96f6fc500a53

무선랜 접속은 MAC80211 드라이버가 필요한데, 이에 딸린 식구들이 상당히 많음을 알 수 있을것이다.

 

그리고 네트웍 인터페이스 이름이 wlx7cdd90a9d2d2이나 wlx7cdd908691bf처럼 random하게 보인다.

lan0 같은 구식 이름으로 변경하려면 어떻게 해야 할까?

몇가지 방법이 있는것 같은데 임베디드 리눅스에서는 Kernel parameter에 "net.ifnames=0"을 추가하면 된다고 한다.

USB 무선랜을 AP모드로 동작시키려면 구식 이름이 편리한것 같아 준비할 필요가 있어 보인다.

Buildroot에서도 동일한 현상이 있다면 적용해보자.

 

 

이제 임베디드 리눅스 시스템의 기본 구색은 모두 갖춘것 같으니 부팅속도 최적화에 좀 집중을 해볼까 한다.

'임베디드' 카테고리의 다른 글

쾌속 부팅 2차 도전  (0) 2020.01.14
쾌속 부팅을 향한 첫 걸음  (0) 2020.01.13
SPI 포트 기능 테스트  (3) 2020.01.11
UART 포트 기능 테스트  (0) 2020.01.10
Buildroot 테스트  (0) 2020.01.06