ルーターに USB を生やせ!

本記事はルーターハックAdvent Calendar 8日目の記事です。

わやくそ遅れていて申し訳ない。

さて。今日は もともと USB ポートのないルーターに USB を生やす 回である。SoC に USB PHY があるのに使わないというのはもったいない。ハードオフの青いかごで眠っていた324円のルーターと一緒に、次なる高みを目指そうじゃないか。

おことわり

技適 に関する筆者の配慮や考えについてはカレンダー1日目「技適とルーターハック」をご覧ください。本記事で紹介する内容は、法を遵守するための慎重な注意をもって書かれています。

www.zopfco.de

ひとまずはんだ付け

先日からハックの犠牲になってもらっている Buffalo WHR-G301N を改造する予定だったのだが、ミスってリアルに犠牲になってしまったので(苦笑)、スペックの近い代用品として改造済み WHR-HP-GN を利用する。利用できる遺産は利用していこう。

WHR-G301N にも WHR-HP-GN にも USB ポートはないが、SoC には USB PHY が搭載されている。

f:id:puhitaku:20181210231711p:plain
データシート。

USB は差動通信するので DP と逆相の DN がある。この2本を接続すれば原理的には通信できそうだ。というわけで接続したのが以下。

f:id:puhitaku:20181216001514j:plain

ファーム側でUSB有効化…のはずが

WHR-HP-GN や WHR-G301N を含む Atheros のチップを搭載した機種(アーキテクチャ名 ar71xx)は、OpenWrt において大きな転換点を迎えている。というのも、もともとはハードウェアの初期化のために機種ごとに異なるCのコードが用意されていたのだが、新しいアーキテクチャ名 ath79 として Device Tree による実装に置き換えられつつあるのだ。(情報をくださったmusashino_205さんに感謝

この流れに乗ろうと WHR-HP-GN も DTS 化を目指した。幸運にもハード的には WHR-HP-G300N とほぼ同じなので、実質的にそれの DTS を使えば WHR-HP-GN も初期化できる。もともとの初期化コードにも WHR-HP-G300N の隣に WHR-HP-GN の記述がなされていることが確認できる

各種記述を追加して早速やってみたのだが、USB を有効化してもprobeがうまくいかない。正確には probe というか、物理層が何かしらうまく行っていない感じだ。

[  431.775895] usb 1-1: new full-speed USB device number 2 using ohci-platform
[  432.065887] ohci-platform 1b000000.usb: frame counter not updating; disabled
[  432.072990] ohci-platform 1b000000.usb: HC died; cleaning up
[  436.836023] usb usb1-port1: attempt power cycle

USB は何かと闇が深いスタックで本業でも泣かされてきたので、今回はひとまず深堀りはやめて DTS ベースの初期化は諦めた。実を言うと ar71xx ベースでの USB 追加は以前やって発表したものと全く同じになるので避けたかったのだが。

初期化コードを加工する

openwrt/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c に以下のような加工を加える。見た目通りって感じ。

diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c
index 48f49ad0f7..84ee3c8a4c 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-whr-hp-g300n.c
@@ -21,6 +21,7 @@
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-m25p80.h"
+#include "dev-usb.h"
 #include "machtypes.h"

 #define WHRHPG300N_GPIO_LED_SECURITY           0
@@ -123,6 +124,8 @@ static void __init whrhpg300n_setup(void)
                                    AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
                                    AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN);

+       ath79_register_usb();
+
        ath79_register_leds_gpio(-1, ARRAY_SIZE(whrhpg300n_leds_gpio),
                                 whrhpg300n_leds_gpio);

カーネルモジュールを追加する

USB という物理層自体のドライバに加え、それ以上のレイヤーのドライバ、例えば USB storage を扱うドライバなどを追加しなければデバイスは利用できない。以前紹介した make menuconfig で追加していく。USB メモリを使うとして、主に必要なのは

  • Target System -> Atheros AR7xxx/AR9xxx
  • Kernel Modules -> USB Support -> kmod-usb-core
  • Kernel Modules -> USB Support -> kmod-usb-ohci
  • Kernel Modules -> USB Support -> kmod-usb-storage
  • Kernel Modules -> Filesystems -> kmod-fs-ext4
  • Kernel Modules -> Native Language Support -> kmod-nls-iso8859-1

といったところ。

挿してみる

手元にあった適当なUSBメモリを挿してみる。

[   86.223642] usb 1-1: new full-speed USB device number 3 using ohci-platform
[   87.638134] usb-storage 1-1:1.0: USB Mass Storage device detected
[   87.647383] scsi host0: usb-storage 1-1:1.0
[   88.680846] scsi 0:0:0:0: Direct-Access     UFD 3.0  Silicon-Power8G  PMAP PQ: 0 ANSI: 6
[   89.588758] sd 0:0:0:0: [sda] 15306752 512-byte logical blocks: (7.84 GB/7.30 GiB)
[   89.601729] sd 0:0:0:0: [sda] Write Protect is off
[   89.611736] sd 0:0:0:0: [sda] No Caching mode page found
[   89.617179] sd 0:0:0:0: [sda] Assuming drive cache: write through
[   89.680778] random: crng init done
[   89.690053]  sda: sda1
[   89.723805] sd 0:0:0:0: [sda] Attached SCSI removable disk

うん、いい感じ。見慣れたログが出る。マウントはどうか?中身のファイルシステムが何かも忘れてるけど。

root@OpenWrt:~# cd
root@OpenWrt:~# pwd
/root
root@OpenWrt:~# mkdir mnt
root@OpenWrt:~# mount /dev/sda1 mnt/
[  170.459769] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
root@OpenWrt:~# ls mnt/
System Volume Information  efi
boot                       keymap.pro
bootmgr                    reagent.xml
bootmgr.efi                sources

マウント成功。どうやら Windows のリカバリ USB のようだ。関係ないが keymap.pro は NiZ Plum のキーマップファイルだ。

USBは無限大

USBが挿さるということは、健康なギーク男子が想像するようなあんなものやこんなものが挿さってしまうということだ。さりとて、USB Storage こそ USB 機器の基本ともいえる。実際こいつが使えると rootfs の拡張がいとも簡単に成し遂げられてしまうし、ハックの幅を広げる第一歩ともいえるだろう。

次回は、USB メモリを実際に rootfs を広げる道具として使い、GCC を入れたりルーターの上で make をビルドしたりしてみたいと思う。なんだかLFSチックな話で胸が踊る。