□OrangePiを、USB-OTGを使って、T〇SHIBAのRE〇ZAのUSB接続機器にする
昨年、ついに我が家にもテレビ(東芝のREGZA)が来た!
家のLAN環境を大幅に改善して、といってもLANケーブルを各部屋に配線したくらいだけど、ストレージサーバーを作ろうと目論んでいた。
が、最近のREGZA(だけじゃないのかな?)はいわゆるNAS(sambaとか)に録画できない、という情報を村役場で得ました。(Thanks @nogisawa)
家に帰って説明書を読むと、たしかに最近のはできないらしい。以前のはできたのに!なんというデグレードだ!
…しょうがない、ストレージサーバーはあきらめてUSB接続もできるNASにするか、と、途方に暮れていた。
でもよく考えると、このストレージサーバーって中身がLinuxじゃないの???
つまるところ、Raspberry Pi(RasPi)みたいなのでUSBストレージもどきにして、そこに録画できるのでは?と思いついた。
その後いろいろ調べてみると、USB OTG(USB On-The-Go)という機能を使うことで、RasPiをUSBストレージにするという記事(※)をいくつか見つけることができた。
Raspbianでということならば、Orange Pi(OPi)にArmbianでもできるだろう、と調べ続けていたら、さすが鹿児島LUG(KagoLUG)の@matokenさんの記事(※)も見つけることができた。(これたぶん昔見たはずだ…)
※[メモ] Raspberry Pi ZeroをUSBマスストレージデバイスとして使う
※*PiをUSBゲームパッドとして動作させる
RasPiの場合にはZEROでないとUSB-OTGがないが、速度を考えるとRasPi3とかの方がいいだろうなー、と思って調べてみたら、USB-OTGがついているのはLANポートがないタイプ(AとかZERO)しかないらしい。
さすがにどっちも持っていないので、買ったけど積んで放置していたOrange Pi(OPi)のPlus 2E(Opi2E)を使うことにする。
OPiもUSB-OTGが付いているのと付いていないのがあるが、手持ちのOpi2EはOTG対応のUSBポートが一つある。(ま、OPiの場合にはUSB-OTG以外にWiFiの有無、という技適問題があるんだけどね)
というわけで、今回はOPi用のArmbianを使って、USB-OTG機能を有効にして、OPiの接続機器からはUSBストレージとして見えるように構築してみる。
・Armbian
にいろいろなマイコンボート用のArmbianがある中から、OPi2E用のArmbianを落としてくる。
SDスロットがあるLinuxマシンで(Windowsでもいいけど、やることは落としてきたイメージを展開してmicroSDに焼けばいいだけだし…)
mkdir /usr/src/package cd /usr/src/package wget https://dl.armbian.com/orangepiplus2e/archive/Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.7z 7z x ./Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.7z
ダウンロードしてきたら、microSDを挿して
cd ~ umount /dev/mmcblk0p* dd if=/usr/src/package/Armbian_5.35_Orangepiplus2e_Debian_jessie_default_3.4.113.img of=/dev/mmcblk0 bs=512M
そしたらArmbianのデフォルトパスワード「root/1234」でログインしてrootのパスワードを新しくする。
さらに新しいユーザーとそのパスワードを設定。
で、簡単にArmbianの設定。
・ディスプレイモードの変更
h3disp -m 32
とかで1024×768のディスプレイモードになる。(1920×1200はない)
・eMMCにコピー。
OPi2Eは16GBのeMMCが搭載されている。(読み書き速度は50MB/s以上出るよ!!)
microSDからの起動はかったるいのでeMMCにコピーしてしまう。
armbian-config
で、 System→Install→eMMCにコピー
・タイムゾーンも日本(JST)に
さらに、Personal→Timezone→ASIA/Tokyo、で日本時間にする。
他にも、いろいろ設定できるけど、とりあえず肝心の設定に進むのでarmbian-configを抜ける。
・最新のシステムにバージョンアップ
apt-get -y update;apt-get -y upgrade
・日本語化
…は、しない方がいいかな?表示が字化けても嫌だし。:-)
やりたい人は
apt-get -y install language-pack-ja-base language-pack-ja ibus-mozc localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja" source /etc/default/locale echo $LANG
ちなみにGUIも入れるならそっちもそっちで変更が必要なので、めんどい。(笑)
・本題のUSB-OTG化
カーネルのUSBガジェットモジュールを見てみると、
ls -al /lib/modules/3.4.113-sun8i/kernel/drivers/usb/gadget
> -rw-r–r– 1 root root 31292 Nov 22 21:45 dummy_hcd.ko
> -rw-r–r– 1 root root 29488 Nov 22 21:45 gadgetfs.ko
> -rw-r–r– 1 root root 43740 Nov 22 21:45 g_audio.ko
> -rw-r–r– 1 root root 65076 Nov 22 21:45 g_cdc.ko
> -rw-r–r– 1 root root 68724 Nov 22 21:45 g_ether.ko
> -rw-r–r– 1 root root 39804 Nov 22 21:45 g_hid.ko
> -rw-r–r– 1 root root 60836 Nov 22 21:45 g_mass_storage.ko
> -rw-r–r– 1 root root 114572 Nov 22 21:45 g_multi.ko
> -rw-r–r– 1 root root 51436 Nov 22 21:45 g_ncm.ko
> -rw-r–r– 1 root root 30040 Nov 22 21:45 g_printer.ko
> -rw-r–r– 1 root root 54176 Nov 22 21:45 g_serial.ko
> -rw-r–r– 1 root root 40208 Nov 22 21:45 g_zero.ko
肝心の「g_mass_storage.ko」がある。
とりあえず2GB程度のストレージ領域イメージファイルをeMMCに作る。
dd if=/dev/zero of=/var/tmp/test.img bs=1M count=2048
そして、このストレージ領域イメージファイルにfdiskでパーティションを作成して、typeをcにしてVFATにする。
fdisk /var/tmp/test.img
VFATにしたら、ループバックデバイスとしてマウントしてフォーマットする。
losetup -o 1024k /dev/loop0 /var/tmp/test.img mkfs.vfat /dev/loop0 losetup -d /dev/loop0 sync sync sync
これでストレージ領域イメージファイルの準備ができたので、「g_mass_storage.ko」モジュールを使ってUSBストレージにする。
rmmod g_mass_storage modprobe g_mass_storage file=/var/tmp/test.img stall=0
※stall=0がポイント、で、echo 2することで有効になる。
で、dmesgすると、
> [ 101.822392] usb open backing file: /var/tmp/test.img, 0xee495400
> [ 101.822767] g_mass_storage gadget: Mass Storage Function, version: 2009/09/11
> [ 101.822810] g_mass_storage gadget: Number of LUNs=1
> [ 101.822883] lun0: LUN: removable file: /var/tmp/test.img
> [ 101.822960] ep_matches, wrn: endpoint already claimed, ep(0xc09791ac, 0xbf210c1c, ep1in-bulk)
> [ 101.823023] g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11
> [ 101.823073] g_mass_storage gadget: userspace failed to provide iSerialNumber
> [ 101.823137] g_mass_storage gadget: g_mass_storage ready
となって、準備完了。
OPi2EのOTG対応USBはmicroUSBポートなので、ここにUSBケーブルをさして、まずはPCなどにつないでみるといい。
> [ 125.343731] g_mass_storage gadget: high-speed config #1: Linux File-Backed Storage
OPi2E側ではこのようになって、PC側でもストレージが現れる!
ただし、PC側でアンマウントしても、OPi2E側では何も出てこない。
ケーブルを抜いても何もならない。もう一度ケーブルをさすと、またPC側でストレージが現れ、OPi2E側でも
> [ 285.319586] g_mass_storage gadget: high-speed config #1: Linux File-Backed Storage
となって、また認識するだけ。
あとはディスクベンチマークソフト(CrystalDiskMarkとか)で、ひとまずeMMCでの性能測定をしてみる。
eMMCを対象に50MBでテスト
eMMCを対象に1GBでテスト
だいたい20MB/s(160Mbps)くらい出ているのが判る。
@nogisawa 君曰く
「1つの録画で必要な帯域は多めに見積もっても30Mbps。余裕だと思う」
「USB 2.0の実測値って感じの速度な気がする」
ということなので、これでいいらしい。
・ストレージはNFSに
参考:https://www.server-world.info/query?os=Debian_8&p=nfs&f=2
本来の目標はネットワークでつながったストレージサーバーを構築したい。
なので、OPi2Eはあくまで「USB←→LANストレージコンバーター」的な役割をしてもらう。
そして実際のストレージは、OPi2EのArmbianからみてNFSでマウントした、ネットワーク上の別のNFSサーバーのストレージとする。
はたしてNFSサーバーのストレージの速度は、録画の書き込み速度に間に合うのか!?
というわけで、まずはNFSサーバーを用意して、Armbianからマウントしてみる。
apt-cache search nfs apt-get -y install nfs-common nfstest
mkdir /stock mount -t nfs4 192.168.192.123:/ /stock -o hard,intr
df -h
> Filesystem Size Used Avail Use% Mounted on
> /dev/mmcblk0p1 15G 3.1G 11G 23% /
> udev 10M 0 10M 0% /dev
> tmpfs 403M 5.6M 398M 2% /run
> tmpfs 1008M 0 1008M 0% /dev/shm
> tmpfs 5.0M 4.0K 5.0M 1% /run/lock
> tmpfs 1008M 0 1008M 0% /sys/fs/cgroup
> tmpfs 1008M 0 1008M 0% /tmp
> log2ram 50M 2.7M 48M 6% /var/log
> tmpfs 202M 0 202M 0% /run/user/0
> 192.168.192.123:/ 16G 4.2G 11G 29% /stock
というように、NFSサーバーのストレージがNFSでマウントできたので、いざ速度を測定してみる。
apt-get -y install fio fio --name=/stock/fiodiskmark --rw=randread --size=50m --name=job1
> READ: io=51200KB, aggrb=8017KB/s, minb=8017KB/s, maxb=8017KB/s, mint=6386msec, maxt=6386msec
50MBの読み込みで実質8MB/s!?…遅くない?
fio --name=/stock/fiodiskmark --rw=randread --size=1024m --name=job1
> READ: io=1024.0MB, aggrb=8558KB/s, minb=8558KB/s, maxb=8558KB/s, mint=122519msec, maxt=122519msec
1GBの読み込みにしても実質8.5MB/s?…遅くないか???
続いて、ddで1GBの書き込み速度を計測してみる。
time dd if=/dev/zero of=/stock/fiodiskmark.0.0 bs=1M count=1000
NFS経由で三回書き込んでみた平均は62MB/秒!…速い!
ただ、これはArmbianからNFSサーバーへの読み書きなので、ストレージコンバーターとしての変換処理が入るとどうだろう?
・最終確認
では最後に
[REGZA…のつもりのPC(Win10)]
↑
(g_mass_storage/USB2.0)
↓
[OPi2E]
↑
(NFS/GbE)
↓
[R610 vps-home:/stock/]
を試してみる。
KVMな仮想環境にストレージサーバーを構築(ストレージ部分のディスクは2.5inchSAS、10kRPM、300GBでRAID-0)した。そこに先のテストと同様に、4GBのストレージ領域イメージファイルを作る。
dd if=/dev/zero of=/stock/test.img bs=1M count=4096
そして、このストレージ領域イメージファイルにfdiskでパーティションを作成して、typeをcにしてVFATにする。
fdisk /stock/test.img
VFATにしたら、ループバックデバイスとしてマウントしてフォーマットする。
losetup -o 1024k /dev/loop0 /stock/test.img mkfs.vfat /dev/loop0 losetup -d /dev/loop0 sync sync sync
これでストレージ領域イメージファイルの準備ができたので、「g_mass_storage.ko」モジュールを使ってUSBストレージにする。
rmmod g_mass_storage modprobe g_mass_storage file=/stock/test.img stall=0
有効にしたら、さっそくテスト。
NFS先を対象に50MBでテスト
NFS先を対象に1GBでテスト
結果としては、Readは20MB/s以上出るけど、Writeが16MB/s前後しか出ない。
@nogisawa 君の言うように、これがUSB2.0の限界なのか?
で、この仕組みを起動時に自動的に実行させるには、/etc/rc.localにでも
/sbin/modprobe g_mass_storage file=/stock/test.img stall=0 iProduct="OPi Storage Bridge" /bin/echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role
のようにすればよい。
・今後の改善検討
今回の構成ではバーチャルマシン(VM)の上のNFSという構成なのでオーバーヘッドが少しあるのかも?と思い、ホストに別のディスクイメージを用意して、それを直接NFSさせるのがよいのでは?と思って試してみた。
modprobe g_mass_storage file=/dev/vdb stall=0
だが、あまり速度の改善は見られなかった。
ではストレージコンバーターとして使用するマシンをOPi2Eではなく、もっと早いマシンにしたらどうだろう?
ということで、さっそくArmbianで他のマイコンボードをみたりOrange Piのサイトを見たりした。そしたら、「Orange Pi One Plus」(H6)と「Orange Pi PC2」(H5)がWi-Fiを積んでいなくて、かつOPi2Eよりも速そうだ。
ということでさっそくAliExpressでこれらをポチったので、これで作ってみた。
Orange Pi One Plus
Orange Pi PC2
OPi PC2のmicroSDを対象に100MBでテスト
OPi PC2をストレージコンバーターとしてNFS先を対象に100MBでテスト
OPi PC2をストレージコンバーターとしてNFS先を対象に1GBでテスト
…というように、あまり変わらなかった。というか、H3よりH5の方が遅いの!?
(それでも書き込み速度は112Mbpsは確保できそうだけど)
結局USB2.0である限り、もう少しストレージコンバーターに使うマイコンボードにコストをかけても、これくらいが限界値なのかもしれない。
左からOne Plus、PC2、Plus 2E
USB3.0のUSB-OTGを搭載しているマイコンボードが「格安」であれば、それで試しても面白いかもしれない。
ただし、REGZAのUSBが2.0である限り、意味がないけれど。 😛
で、
□ストレージコンバーター化したOrangePiをT〇SHIBAのRE〇ZAに繋いでみた
に続きます。 🙂