はじめに
ELECOM製の WDC-433DU2H2-B をRaspberry Pi4 Model Bで使用するために必要なカーネルモジュールのビルドについて解説します。
WDC-433DU2H2-B と RTL8821AU
WDC-433DU2H2-B は WDC-433DU2HBK に次いで発売された大型アンテナがついたWiFiドングル。Realtek製のWiFiコントローラーチップ RTL8811AU を採用しているようだが、RTL8821AU用のカーネルモジュールにて動作させることが可能。実行環境
実機: Raspberry Pi 4 Model B
OS: Rasbian Buster Light
Kernel version: 4.19.97
別にRPi4でなくても大丈夫だが、カーネルのバージョンが古くなると下記の方法ではうまくいかない可能性が出てくる。
作業のサマリ
- カーネルソースをDLして、make modules_prepareを実行
- GitHubよりdiederikdehaas/rtl8812AU (https://github.com/diederikdehaas/rtl8812AU) の ブランチ driver-4.3.22-beta をclone
- rtl8812AU/os_dep/linux/usb_intf.c の 8821 セクションに WDC-433DU2H2-B のVID&PIDを書き加える。
- コンパイルとインストール
カーネルソースのダウンロード、コンパイル
詳細は、例えばこちらの小生の記事を参照されたし。
https://qiita.com/newtypehiro919/items/336e09340e728a94a9f7
カーネルモジュールのコンパイル
ソースのダウンロード
diederikdehaas/rtl8812AU を利用する。
(https://github.com/diederikdehaas/rtl8812AU/tree/driver-4.3.20)
番号が8812なのは間違いではない。8812用と8821用のカーネルモジュールが同時提供されていることはよくある。
ブランチ driver-4.3.22-beta
を clone する。デフォルトのブランチをcloneしてもうまくいかない! デフォルトの driver-4.3.20
には、目的としているrtl8821auのコードが含まれていない。
git clone -b driver-4.3.22-beta https://github.com/diederikdehaas/rtl8812AU.git
ソースの編集
カーネルモジュールが WDC-433DU2H2-B を認識できるように、Vender ID と Product ID をソースファイル中に書き込む必要がある。なお、WDC-433DU2H2-B の Vender ID は0x056E
、Product ID は0x4010
である。
#ifdef CONFIG_RTL8821A
/*=== Realtek demoboard ===*/
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0811),.driver_info = RTL8821},/* Default ID */
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0821),.driver_info = RTL8821},/* Default ID */
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8822),.driver_info = RTL8821},/* Default ID */
{USB_DEVICE(USB_VENDER_ID_REALTEK, 0xA811) , .driver_info = RTL8821},/* Default ID */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0820,0xff,0xff,0xff),.driver_info = RTL8821}, /* 8821AU */
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDER_ID_REALTEK, 0x0823,0xff,0xff,0xff),.driver_info = RTL8821}, /* 8821AU */
/*=== Customer ID ===*/
{USB_DEVICE(0x0411, 0x0242),.driver_info = RTL8821}, /* BUFFALO - Edimax */
{USB_DEVICE(0x04BB, 0x0953),.driver_info = RTL8821}, /* I-O DATA - Edimax */
{USB_DEVICE(0x056E, 0x400E),.driver_info = RTL8821}, /* ELECOM - ELECOM */
{USB_DEVICE(0x056E, 0x400F),.driver_info = RTL8821}, /* ELECOM - ELECOM */
{USB_DEVICE(0x0846, 0x9052),.driver_info = RTL8821}, /* Netgear - A6100 */
{USB_DEVICE(0x0E66, 0x0023),.driver_info = RTL8821}, /* HAWKING - Edimax */
{USB_DEVICE(0x2001, 0x3314),.driver_info = RTL8821}, /* D-Link - Cameo */
{USB_DEVICE(0x2001, 0x3318),.driver_info = RTL8821}, /* D-Link - Cameo */
{USB_DEVICE(0x2019, 0xAB32),.driver_info = RTL8821}, /* Planex - GW-450S */
{USB_DEVICE(0x3823, 0x6249),.driver_info = RTL8821}, /* Obihai - OBiWiFi */
{USB_DEVICE(0x7392, 0xA811),.driver_info = RTL8821}, /* Edimax - Edimax */
{USB_DEVICE(0x7392, 0xA812),.driver_info = RTL8821}, /* Edimax - EW-7811UTC */
{USB_DEVICE(0x7392, 0xA813),.driver_info = RTL8821}, /* Edimax - EW-7811UAC */
/* この下の1行を追加。WDC-433DU2H2-B の VID & PID */
{USB_DEVICE(0x056E, 0x4010),.driver_info = RTL8821},
#endif
#ifdef CONFIG_RTL8821A
のセクションに {USB_DEVICE(0x056E, 0x4010),.driver_info = RTL8821},
の1行を書き加える。なお、コンマで終わっているが、間違いではない。
Makefileの編集
ラズパイ用のカーネルモジュールをコンパイルするので、CONFIG_PLATFORM_I386
を n
にして、CONFIG_PLATFORM_ARM_RPI
を y
に書き換える。
CONFIG_RTW_SDIO_PM_KEEP_POWER = y
###################### Platform Related #######################
CONFIG_PLATFORM_I386_PC = n /* y から n に変更する */
CONFIG_PLATFORM_ARM_RPI = y /* n から y に変更する */
CONFIG_PLATFORM_ARM64 = n
CONFIG_PLATFORM_ANDROID_X86 = n
CONFIG_PLATFORM_ANDROID_INTEL_X86 = n
コンパイル
make コマンドを実行する。-j4
オプションを付けた方が少しコンパイルが早くなる。
ところどころで Warning が出るが、コンパイルはできる。
raspberrypi:/usr/src/rtl8812AU# make -j4
make ARCH=arm CROSS_COMPILE= -C /lib/modules/4.19.97-v7l+/build M=/usr/src/rtl8812AU modules
make[1]: Entering directory '/usr/src/linux-43857965e5f526b9df807e543102a11fac1c0bcc'
CC [M] /usr/src/rtl8812AU/core/rtw_cmd.o
CC [M] /usr/src/rtl8812AU/core/rtw_security.o
CC [M] /usr/src/rtl8812AU/core/rtw_debug.o
CC [M] /usr/src/rtl8812AU/core/rtw_io.o
(中略)
CC [M] /usr/src/rtl8812AU/hal/led/hal_usb_led.o
CC [M] /usr/src/rtl8812AU/hal/HalPwrSeqCmd.o
/usr/src/rtl8812AU/hal/hal_hci/hal_usb.c: In function ‘usb_init_recv_priv’:
/usr/src/rtl8812AU/hal/hal_hci/hal_usb.c:38:3: warning: cast between incompatible function types from ‘void (*)(void *)’ to ‘void (*)(long unsigned int)’ [-Wcast-function-type]
(void(*)(unsigned long))usb_recv_tasklet,
^
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/Hal8812PwrSeq.o
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/Hal8821APwrSeq.o
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/rtl8812a_xmit.o
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/rtl8812a_sreset.o
(中略)
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/usb/rtl8812au_recv.o
CC [M] /usr/src/rtl8812AU/hal/rtl8812a/usb/usb_ops_linux.o
CC [M] /usr/src/rtl8812AU/hal/efuse/rtl8812a/HalEfuseMask8812A_USB.o
/usr/src/rtl8812AU/hal/rtl8812a/usb/rtl8812au_xmit.c: In function ‘rtl8812au_init_xmit_priv’:
/usr/src/rtl8812AU/hal/rtl8812a/usb/rtl8812au_xmit.c:33:7: warning: cast between incompatible function types from ‘void (*)(void *)’ to ‘void (*)(long unsigned int)’ [-Wcast-function-type]
(void(*)(unsigned long))rtl8812au_xmit_tasklet,
^
CC [M] /usr/src/rtl8812AU/hal/efuse/rtl8812a/HalEfuseMask8821A_USB.o
CC [M] /usr/src/rtl8812AU/hal/phydm/phydm_debug.o
CC [M] /usr/src/rtl8812AU/hal/phydm/phydm_antdiv.o
(中略)
CC [M] /usr/src/rtl8812AU/core/rtw_mp_ioctl.o
CC [M] /usr/src/rtl8812AU/core/rtw_bt_mp.o
/usr/src/rtl8812AU/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c: In function ‘_IQK_Tx_8821A’:
/usr/src/rtl8812AU/hal/phydm/rtl8821a/phydm_iqk_8821a_ce.c:646:174: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("RX_X0[1][%d] = %x ;; RX_Y0[1][%d] = %x\n", i, (RX_X0[1][i])>>21&0x000007ff, i, (RX_Y0[1][i])>>21&0x000007ff));
^
LD [M] /usr/src/rtl8812AU/8812au.o
Building modules, stage 2.
MODPOST 1 modules
CC /usr/src/rtl8812AU/8812au.mod.o
LD [M] /usr/src/rtl8812AU/8812au.ko
make[1]: Leaving directory '/usr/src/linux-43857965e5f526b9df807e543102a11fac1c0bcc'
raspberrypi:/usr/src/rtl8812AU#
この下から3行目にある 8812au.ko
が求めるカーネルモジュール。
ただし、kernel version 4.19.97 でのみ有効なモジュール。後に apt upgrade
など実行してカーネルのバージョンが変わってしまうと、カーネルソースの取得からカーネルモジュールのコンパイルまで、全部やり直さないといけなくなるので注意が必要。
カーネルモジュールのインストール
コンパイル終了後に下記コードを実行すれば終了。
make install
modinfo コマンドで確認してみる。カーネルモジュール名は8812au
raspberrypi:/usr/src/rtl8812AU# modinfo 8812au
filename: /lib/modules/4.19.97-v7l+/kernel/drivers/net/wireless/8812au.ko
version: v4.3.22-beta
author: Realtek Semiconductor Corp.
description: Realtek Wireless Lan Driver
license: GPL
srcversion: CB90FC4561203545235BE0B
alias: usb:v7392pA813d*dc*dsc*dp*ic*isc*ip*in*
alias: usb:v7392pA812d*dc*dsc*dp*ic*isc*ip*in*
alias: usb:v7392pA811d*dc*dsc*dp*ic*isc*ip*in*
(以下、省略)
再起動してWiFiドングルが認識されれば成功!
検証済みのこと
とりあえず、子機として動く(アクセスポイントに接続して通信できる)。
APモードでも動く。ただし、自分が hostapd の設定に明るくないので、フルスペックが引き出せているかは不明。パフォーマンステストまではしてない。