本記事はルーターハックAdvent Calendar 9日目の記事です。
これは、遅れを取り戻す物語。(コピー風)(このリズム感どっかで聞いたことあると思ったらFGOでした。FGO1ミリもしらんけど。)
8日目の記事では、USB ポートのないルーターに USB を生やして使えるようにするまでを書いた。こいつを使えば、USB メモリでルーターの rootfs(Windows でいう C ドライブ)の容量を拡張して好き勝手やることができる。今回は、GCCをインストールして Python をビルドしてみよう。
なぜ遅れを取り戻さなければならないのに時間がかかるネタをやろうとするのかは筆者自身でも不明である。
おことわり
技適 に関する筆者の配慮や考えについてはカレンダー1日目「技適とルーターハック」をご覧ください。本記事で紹介する内容は、法を遵守するための慎重な注意をもって書かれています。
SDカードを準備
やろうと思えば opkg を使ってルーターに fdisk や mkfs.ext4 も入れられるのだが、面倒なのでPC側でフォーマットしてしまった。
前半 7000 MiB を ext4 でフォーマットし、残る容量を swap とした。WHR-HP-GN のメインメモリは32 MiB と大変少ないので、swap がなければまず GCC の動作は無理だろう。
SD カードを rootfs の拡張領域にする
OpenWrt は何もせずとも overlayfs を用いてメインストレージ(多くの場合 SPI Flash)の固定された rootfs と書き換え可能な領域を分割して提供する。これを pivot_root (2) で置き換える形で、外部ストレージもまた rootfs の overlay として使うことができる。
これからの作業は公式のマニュアルにも記載されている。ぜひ参照されたい。
まず必要な道具として以下を make
で追加しビルド。
Utilities
->Filesystem
->swap-utils
Global build settings
->Kernel build options
->Support for paging of anonymous memory (swap)
Base system
->block-mount
Base system
->busybox
->Linux System Utilities
->swapon
swapoff
Customize busybox options
にチェックを入れると出現
生成されたら ssh で転送して sysupgrade しよう。
ここで SD カードリーダーを挿入し、 block detect
を実行すると以下のようにファイルシステムが認識される。 これは /etc/config/fstab
として置く設定ファイルを自動生成するコマンドだ(実行するだけでは書き換えられない)。
root@OpenWrt:~# block detect config 'global' option anon_swap '0' option anon_mount '0' option auto_swap '1' option auto_mount '1' option delay_root '5' option check_fs '0' config 'mount' option target '/mnt/sda1' option uuid '31407de4-3283-4dfd-b391-375cc78c9a04' option enabled '0' config 'swap' option uuid '49c9c539-29d9-4f56-b775-691b1fcdff86' option enabled '0'
認識していることが確認できたら、現在の overlayfs に置いてあるファイルを SD カードにコピーする。公式ドキュメントでは tar
を使ってちょっとテクいことをしているが、普通にコピーすれば OK だ。
root@OpenWrt:~# mount /dev/sda1 /mnt [ 3669.913854] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null) root@OpenWrt:~# cp -r /overlay/ .fs_state upper/ work/ root@OpenWrt:~# cp -r /overlay/* /mnt/
最後に /etc/config/fstab
を生成し、全エントリを有効にする。ext4 なパーティションの mount point は /overlay
に変更する。
root@OpenWrt:~# block detect > /etc/config/fstab root@OpenWrt:~# vi /etc/config/fstab ... root@OpenWrt:~# cat /etc/config/fstab config 'global' option anon_swap '0' option anon_mount '0' option auto_swap '1' option auto_mount '1' option delay_root '5' option check_fs '0' config 'mount' option target '/mnt/sda1' option uuid '31407de4-3283-4dfd-b391-375cc78c9a04' option enabled '1' config 'swap' option uuid '49c9c539-29d9-4f56-b775-691b1fcdff86' option enabled '1'
完了したらリブート!
リブート後…
以下のようなログが出て、df
を見て容量が半端ないことになっていれば成功だ。
[ 12.135475] block: attempting to load /tmp/jffs_cfg/upper/etc/config/fstab [ 12.276824] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: [ 12.452555] mount_root: switched to extroot
root@OpenWrt:/# df -h Filesystem Size Used Available Use% Mounted on /dev/root 2.0M 2.0M 0 100% /rom tmpfs 13.6M 64.0K 13.5M 0% /tmp /dev/sda1 6.7G 16.1M 6.3G 0% /overlay overlayfs:/overlay 6.7G 16.1M 6.3G 0% / tmpfs 512.0K 0 512.0K 0% /dev
あれ?swap が有効になってない。anon_swap を1にしたりしても効かないので、今回はとりあえず手動swaponすることにした。
root@OpenWrt:/# swapon /dev/sda2 [ 65.211586] Adding 698364k swap on /dev/sda2. Priority:-2 extents:1 across:698364k root@OpenWrt:/# free total used free shared buffers cached Mem: 27840 18440 9400 60 1804 4920 -/+ buffers/cache: 11716 16124 Swap: 698364 0 698364
うん、OK。
ビルド環境を整え動作確認
ここからは楽しい冒険の始まりだ。
GCC を入れる
opkg でちゃちゃっと。と思いきや。
root@OpenWrt:/# opkg install gcc Installing gcc (5.4.0-3) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/gcc_5.4.0-3_mips_24kc.ipk Collected errors: * opkg_download: Failed to download http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/gcc_5.4. * opkg_download: Check your network settings and connectivity. * opkg_install_pkg: Failed to download gcc. Perhaps you need to run 'opkg update'? * opkg_install_cmd: Cannot install package gcc.
んんん???ダウンロードに失敗??PCで試すとダウンロードできるのに。
と、ここで opkg の tmpdir は /tmp
なのを思い出す。そうか… gcc のパッケージがメモリに入り切らないんだな!
tmpdir を普通のディレクトリに切り替えて回避。USB 2.0 にも対応してないのでめちゃくそ遅いけど。
root@OpenWrt:~# mkdir cache root@OpenWrt:~# opkg --tmp-dir /root/cache install gcc Installing gcc (5.4.0-3) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/gcc_5.4.0-3_mips_24kc.ipk Installing zlib (1.2.11-2) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/zlib_1.2.11-2_mips_24kc.ipk Installing libbfd (2.27-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/libbfd_2.27-1_mips_24kc.ipk Installing libopcodes (2.27-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/libopcodes_2.27-1_mips_24kc.ipk Installing objdump (2.27-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/objdump_2.27-1_mips_24kc.ipk Installing ar (2.27-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/ar_2.27-1_mips_24kc.ipk Installing binutils (2.27-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/binutils_2.27-1_mips_24kc.ipk Installing libstdcpp (7.3.0-1) to root... Downloading http://downloads.openwrt.org/snapshots/targets/ar71xx/tiny/packages/libstdcpp_7.3.0-1_mips_24kc.ipk Configuring zlib. Configuring libbfd. Configuring libopcodes. Configuring objdump. Configuring ar. Configuring binutils. Configuring libstdcpp. Configuring gcc.
よし入った!
make を入れる
実は make はパッケージで入れなくてもソースコードから bootstrap build ができる。以前はそこまでやっていたが、今回はそれほど M なプレイをしたいわけではないので普通に入れる。
root@OpenWrt:~# opkg install make Installing make (4.2.1-2) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/make_4.2.1-2_mips_24kc.ipk Configuring make.
sl を落としてビルドしてみる
ここで、ほんとに make できるのか往年の sl で試してみる。GitHub から clone するために git-http
をインストールする。
root@OpenWrt:~# opkg install git-http Installing git-http (2.20.0-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/git-http_2.20.0-1_mips_24kc.ipk Installing libopenssl (1.0.2p-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/libopenssl_1.0.2p-1_mips_24kc.ipk Installing git (2.20.0-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/packages/git_2.20.0-1_mips_24kc.ipk Installing libmbedtls (2.13.0-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/libmbedtls_2.13.0-1_mips_24kc.ipk Installing ca-bundle (20180409-3) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/ca-bundle_20180409-3_all.ipk Installing libcurl (7.62.0-1) to root... Downloading http://downloads.openwrt.org/snapshots/packages/mips_24kc/base/libcurl_7.62.0-1_mips_24kc.ipk Configuring libmbedtls. Configuring ca-bundle. Configuring libcurl. Configuring libopenssl. Configuring git. Configuring git-http.
clone そして make。
root@OpenWrt:~# git clone https://github.com/mtoyoda/sl.git Cloning into 'sl'... remote: Enumerating objects: 97, done. remote: Total 97 (delta 0), reused 0 (delta 0), pack-reused 97 Unpacking objects: 100% (97/97), done. root@OpenWrt:~# cd sl root@OpenWrt:~/sl# make gcc -O -Wall -o sl sl.c -lncurses sl.c:41:20: fatal error: curses.h: No such file or directory compilation terminated. make: *** [Makefile:15: sl] Error 1
んんっ。ncurses がない。Python でも ncurses はあったほうがいいので入れておくか。
ncurses がないので入れる
パッケージでは ncurses は用意されていない。GNU から落としてくる。
root@OpenWrt:~# wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz wget: SSL support not available, please install one of the libustream-.*[ssl|tls] packages as well as
んんんっw ヤクの毛を刈る感じがしてきたぞw
httpsに必要なあれこれを入れる。
root@OpenWrt:~# opkg install libustream-openssl ca-certificates ... root@OpenWrt:~# wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz Downloading 'https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz' Connecting to 208.118.235.20:443 Writing to 'ncurses-6.1.tar.gz' ncurses-6.1.tar.gz 100% |*******************************| 3286k 0:00:00 ETA Download completed (3365395 bytes)
よし、ビルドだ!
root@OpenWrt:~# tar zxf ncurses-6.1.tar.gz root@OpenWrt:~# cd ncurses-6.1 root@OpenWrt:~/ncurses-6.1# ./configure
もう configure だけで意味わからんぐらい遅くて最高w USB 1.1 は厳しいな…。
configure だけで40分かかった。このあと走らせた make
は実に6時間ぐらいかかってしまった。かなり絶望的なスピードである。
気を取り直して sl
「sl のビルドなんかやろうと思わなきゃよかった」と若干の後悔の念はありつつ、気を取り直してビルド。
root@OpenWrt:~/sl# make gcc -O -Wall -o sl sl.c -lncurses root@OpenWrt:~/sl#
おお?
おおお!!!やったー!
一旦切ります
…さて。ここまでで結構な時間を使ったためちょっと疲れてしまった。この記事は前編として、後編にて Python のビルドに入りたいと思う。