Raspberry Pi B+ の lightMPD を無線LAN接続

スグレモノ (レビュー・評価・評判・口コミ)
RaspberryPiModelB+ と GW-USNANO2A
この記事は約15分で読めます。

以前に Raspberry Pi B+ に SabreBerry+ で lightMPD という記事を書いたが最後に無線化したいけど自分では出来ないと書いていた.

RaspberryPiModelB+ と GW-USNANO2A
RaspberryPiModelB+ と GW-USNANO2A

それがつい先日,Interface 2015年12月号 に「ラズパイ・オーディオの Wi-Fi 化」という記事が出ているのを見かけた.
おぉ!と思い,早速買った.
記事にしていただいてありがとうございます!

この記事では RaspberryPi2 で無線USB子機は GW-450D KATANA という機種だった.

私のは PaspberryPi B+GW-USNANO2Aという組み合わせで,最終的には動いたのだが,割とというか,かなり苦労したので備忘録として残しておく.

自分で見直して再度構築できるようにと思って書いているので本を参照したほうが何をやっているかはよく分かると思います.
(もし,以下の記事の内容に問題あれば削除します.)

詳しくはあくまでも Interface を見てください.
また,あの Interface の記事とは本体もUSBドングルも違うため,ところどころ違っていることに注意してください.

事前準備

まず,クロスコンパイルの環境が必要.
VMWare を使ったことがあるので,今回もそれで行った.

※ちなみに,うちは Windows10 64bit の OS を使っている.

VMware Workstation 12.0.1 Player for Windows 64-bit operating systems. というのをダウンロードしてインストールする.

Ubuntu 15.04 64bit をダウンロードして,VMWare 上でインストールする.
ハードディスクは16GBで作ったが,ディスクがあるなら,20GBの方がよいかもしれない.
「System program problem detected」というダイアログがたまに出ていたが,そのせいかもしれない.(無視しても問題はなかったが.)
基本的に terminal か xterm で作業を行うことになる.

私が使っている lightMPD は raspberry pi b+ なので lightMPDraspi-v1.0.1.zip である.

share などの名前で共有フォルダを作り,以下のファイルをそこに入れておく.
native-dsd再生時のポップノイズに対応したkernelを公開しました
native-dsd-noise-linux-4.0.8.patch

クロスコンパイル環境での準備

sudo apt-get install git
sudo apt-get install libncurses-dev
windows のディスクを見たい場合は
sudo apt-get install cifs-utilsを入れておく.
sudo mount -t cifs -o username=ユーザ名,password=パスワード //WindowsのIPアドレス/share /mnt/windowsなどのように使う.

マウント用ディレクトリの作成.
mkdir /mnt
mkdir /mnt/sd
mkdir /mnt/rootfs

カーネルの再構築

準備

cd
git clone git://github.com/raspberrypi/linux.git
git clone --depth=1 git://github.com/raspberrypi/tools.git
wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.0/older/patch-4.0.5-rt3.patch.xz
cp /mnt/windows/share/native-dsd-noise-linux-4.0.8.patch .
(先ほどダウンロードしたもの)
cd linux
git checkout 520cdbcef82822ae91772297ce4d87ea6f4bedb6 -b lightmpd
(※デバイスドライバの追加)
xzcat ../patch-4.0.5-rt3.patch.xz | patch -p1
vi sound/soc/bcm/bcm2708-i2s.c
(「mash = BCM2708...」の行をコメントアウト)
patch -p1 < ../native-dsd-noise-linux-4.0.8.patch

.config の取り出し

lightMPD の設定を変更し,telnet 出来るようにする.
root でログイン.パスワードはなし.
mount /dev/mmcblk0p1 /mnt
cp /proc/config.gz /mnt
umount /mnt
これで lightMPD の入っている MicroSD のルートに config.gz が保存されるので,これを持ってくる.
この MicroSD を ubuntu を立ち上げた状態の PC に差せば自動でマウントされるが,されない場合は右上のアイコンをクリックして,「接続」を選ぶ./dev/sdb1 に自動でマウントされる.
されない場合は,
mount /dev/sdb1 /mnt/sdなどしてマウント.
cp /mnt/sd/config.gz ~などして,自分のホームディレクトリに持ってくる.

カーネルコンフィグファイルの作成とカーネルコンパイル

(2015/12/22追記:佐藤様からのコメント.下記CROSS_COMPILEの指定で32bitOSを使っている場合は,-x64を削除)
cd ~/linux
zcat ../config.gz > .config
export ARCH=arm
export CROSS_COMPILE=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
make menuconfig

GW-USNANO2A のデバイスのモジュールを入れる.
これは RTL8192CU のドライバを入れればよいことがいろいろ調べてみたら分かった.

以下のドライバである.
Device Drivers > Network device support > Wireless LAN > Realtek 8192C USB Wifi
このモジュールを入れたいのだが,最初表示されない.
そこで,設定画面上で / を打って, 8192 を入れて探す.
そうすると,
Symbol: RTL8192CU [=n] │
│ Type : tristate │
│ Prompt: Realtek 8192C USB WiFi │
│ Location: │
│ -> Device Drivers │
│ -> Network device support (NETDEVICES [=y]) │
│ (1) -> Wireless LAN (WLAN [=y]) │
│ Defined at drivers/net/wireless/rtl8192cu/Kconfig:1 │
│ Depends on: NETDEVICES [=y] && WLAN [=y] && MAC80211 [=n] && USB [=y] │
│ Selects: CFG80211_WEXT [=n] && WIRELESS_EXT [=y] && WEXT_PRIV [=y]
のような感じの表示が出るので,Depends on が全部 y になるように / を使って探しては y にしていく.
モジュールとして入れるので,8192CU は「m」にする.

make -j4 zImage
cp arch/arm/boot/zImage /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

モジュールの作成

上記のように 8192cu のモジュールを入れれば全く問題ないのだが,備忘録で別のドライバのインストール方法も書いておく.この部分は不要.
通常は不要部分.
—ここから—cd ~
git clone https://github.com/dz0ny/rt8192cu.git
cd rt8192cu
sudo bash
export KERNEL_VERSION=`cat include/config/kernel.release`
export INSTALL_MOD_PATH=../$KERNEL_VERSION
make ARCH=arm CROSS_COMPILE=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- -C $INSTALL_MOD_PATH/lib/modules/$KERNEL_VERSION/build M=~/rt8192cu
これでカレントディレクトリに 8192cu.ko が出来る.
(違うドライバは以下のようにコピーする.下で tar する直前)
cp 8192cu.ko $INSTALL_MOD_PATH/lib/modules/$KERNEL_VERSION/drivers/net/wireless/rtl8192cu
—ここまで通常は不要—

モジュールをまとめる.
make modules
export KERNEL_VERSION=`cat include/config/kernel.release`
export INSTALL_MOD_PATH=../$KERNEL_VERSION
make modules_install
/bin/bash ./scripts/depmod.sh /sbin/depmod $KERNEL_VERSION ""
cd $INSTALL_MOD_PATH/lib/modules
(違うドライバを使いたい場合はここでコピーする.)
tar cvzf kmodules.tgz $KERNEL_VERSION
cp kmodules.tgz /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

RAM に入る lightMPD 本体の再作成

initrd.romfs.gz というのがそれである.

buildroot により,wpa_supplicant を作成

cd ~
git clone git://git.buildroot.net/buildroot
cd buildroot/
git checkout -b 2015.05 2015.05
make raspberrypi_dt_defconfig (raspberry piなので)
make menuconfig
Kernel -> Linux Kernel []
Toolchain -> C Library -> glibc
Target package -> Networking applications -> wpa_supplicant [*]
Target package -> Networking applications -> wpa_supplicant -> Install wpa_cli binary [*]
Target package -> Networking applications -> wpa_supplicant -> Install wpa_passphrase binary [*]
make -j4

initrd.romfs.gz の作成

initrd.romfs.gz を展開

cp /mnt/sd/boot/initrd.romfs.gz ~
cd ~
gzip -d initrd.romfs.gz
sudo bash
mount -o loop,ro initrd.romfs /mnt/rootfs
mkdir rootfs
cd rootfs
(cd /mnt/rootfs; tar cf - *) | tar xfBp -

wpa関連ファイルのコピー

cp ../buildroot/output/target/usr/sbin/wpa_* usr/sbin/
head -3 ../buildroot/output/target/etc/wpa_supplicant.conf > etc/wpa_supplicant.conf
wpa_passphrase SSID 事前共有キー >> etc/wpa_supplicant.conf

注意事項:
このファイルに余計なものは加えない.
ネットでググると,
・psk= の先を ” でくくるとうまくいった.
・proto=WPA を設定する.
とかあるが,これらを入れると私の環境では繋がらなくなった.
ここでかなりハマる

SSIDを隠蔽している場合には以下のようにする必要がある.(etc/wpa_supplicant.conf)
...
ap_scan=1
network={
scan_ssid=1
...
scan_ssid=1 を追加するだけでなく,ap_scan=1とnetwork={の間にある改行も削除.head -3 でくっつけると改行が空くがこれがあるせいでなぜか動かない.

システム設定ファイル作成スクリプトを変更

var.rom/lightMPD/bin/syssetup.scm
を以下のように変更
(GW-USNano2(8192cu) は wlan0 になる.)
- (let ((interface (hash-table-get param "interface" "eth0"))
+ (let ((interface (hash-table-get param "interface" "wlan0"))
----
(format port "iface ~a inet static\n" interface)
+ (format port "\t pre-up\t wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf\n")
+ (format port "\t post-up\t sleep 5\n")
+ (format port "\t post-down\t killall -q wpa_supplicant\n")
----
(format port "#!/bin/sh\n\n")
+ (format port "### GW-USNano2 usb Wi-Fi\n")
+ (format port "modprobe 8192cu\n\n")

SSIDを隠蔽している場合には以下のようにする必要がある.
etc/modprobe.d/blacklist.conf
blacklist rtl8192cu

不要ファイルの削除

ここでも大いにハマった
元々あった initrd.romfs.gz を展開して,wpa 関連の実行ファイルをコピーしただけなのにネットワークに接続できなくなるのである.
なぜ動かないのか,2日考えたのだが,どうやら容量オーバーらしい.
Paspberry Pi Model B+ の RAM は 512MB なのだが,initrd.romfs.gz を展開するとこの容量を超えてしまうようなのだ.(正確には512MBではないようだが.)
Raspberry Pi 2 は 1GB なので少々のことでは溢れなさそうだが.

で必要のないファイルは極限まで削ることにする.

rm -rf usr/share/zoneinfo/posix/Pacific
rm -rf usr/share/zoneinfo/posix/Europe
rm -rf usr/share/zoneinfo/posix/Arctic
rm -rf usr/share/zoneinfo/posix/Australia
rm -rf usr/share/zoneinfo/posix/Indian
rm -rf usr/share/zoneinfo/posix/Atlantic
rm -rf usr/share/zoneinfo/posix/America
rm -rf usr/share/zoneinfo/posix/Africa
rm -rf usr/share/zoneinfo/posix/Antarctica
rm -rf usr/share/zoneinfo/posix/US
rm -rf usr/share/zoneinfo/right/Pacific
rm -rf usr/share/zoneinfo/right/Europe
rm -rf usr/share/zoneinfo/right/Arctic
rm -rf usr/share/zoneinfo/right/Australia
rm -rf usr/share/zoneinfo/right/Indian
rm -rf usr/share/zoneinfo/right/Atlantic
rm -rf usr/share/zoneinfo/right/America
rm -rf usr/share/zoneinfo/right/Africa
rm -rf usr/share/zoneinfo/right/Antarctica
rm -rf usr/share/zoneinfo/right/US
rm usr/share/zoneinfo/Africa
rm usr/share/zoneinfo/Atlantic
rm usr/share/zoneinfo/America
rm usr/share/zoneinfo/Australia
rm usr/share/zoneinfo/Antarctica
rm usr/share/zoneinfo/Arctic
rm usr/share/zoneinfo/Europe
rm usr/share/zoneinfo/Indian
rm usr/share/zoneinfo/Pacific
rm usr/share/zoneinfo/US
rm -rf usr/share/locale/de
rm -rf usr/share/locale/fr

initrd.romfs.gz の作成

不要なファイルを削除してスリムになったら,改めてイメージの作成.
genromfs -f ../initrd.romfs
cd ..
gzip initrd.romfs.gz (※オプションの -9 を入れるとSSID隠蔽時に動かない.)
cp initrd.romfs.gz /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

設定ファイルの書き換え

RaspberryPi 用の lightMPD は vmlinux を使うようになっているので,config.txt で zImage を使うように修正する.
#kernel=/boot/zImage

kernel=/boot/zImage
にして,
kernel=/boot/vmlinux

#kernel=/boot/vmlinux
にコメントアウトする.

また,lightmpd.conf の中の eth0 は wlan0 に変更する.

無線ルーターでステルスSSIDを設定している場合

「無線ネットワーク名(SSID)の隠蔽(ANY接続拒否)」を通常「する」で使っていたのだが,これを「する」にすると無線がつながらなくて3日ほど悩んだ.
結局,文中の赤字の部分を設定すればなぜか繋がる.
今回,ここが一番ハマった.
しかも,今でも意味不明な部分もある...偶然見つけた.