ファームの礎『OpenWrt』解説・ビルド編

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

昨日は組み込み Linux の歴史を説明する翻訳記事を掲載した。テンションが高まってきたところで、ルーター向け Linux ディストリビューションである OpenWrt のビルドを解説しよう。

おことわり

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

www.zopfco.de

OpenWrt とは

以下、英語版 Wikipedia からの引用である。

The OpenWrt project was started in 2004 after Linksys had built the firmware for their WRT54G series of wireless routers with code licensed under the GNU General Public License. Under the terms of that license, Linksys was required to make the source code of its modified version available under the same license, which enabled independent developers to create derivative versions. Support was originally limited to the WRT54G series, but has since been expanded to include many other routers and devices from many different manufacturers.

訳: OpenWrt プロジェクトは、2004年、Linksys が WRT54G シリーズのファームウェアを GNU GPL でライセンスされたコードで構築した後に開始された。ライセンス条項により、Linksys は改変が加わったバージョンも同じライセンスで利用可能にすることを求められたため、個人デベロッパーがさらなる派生バージョンを作成することが可能となった。OpenWrt のサポートは当初 WRT54G のみに限られていたが、それから多くのメーカーのあらゆる機器やルーターへと拡張されてきた。

Linux はご存知の通り GNU GPL でライセンスされている。そのため、Linux 入りの機器であれば誰でもメーカーからソースコード(とその他の GPL を採用している OSS のコード)を手に入れられる。その中から取り出した機器特有のコードや設定を一箇所に集合させたのが OpenWrt ということになる。

OpenWrt のビルドシステムは Buildroot をベースに改造を施したもので、もちろんカーネルだけでなくソフト全部入りの rootfs もビルドできるし、これらを一つのバイナリにしたファームウェアそのものもビルドできる。(Buildroot の歴史については昨日の翻訳記事を参照)

LEDE との関係

2016年に、「協調性・透明性・非中央集権化に注力」し「OpenWrt の再起動 (reboot)」を標榜する LEDE (Linux Embedded Development Environment) が OpenWrt から fork し、活力のある開発者は実質的に LEDE へとごっそり移った。開発のアクティビティが低迷する中で新しい開発者が流入しにくいコミュニティ運営ややたら遅くて不安定なサーバーなど、OpenWrt の様々な問題点に業を煮やしていたようだ*1。以降は、別個の新しい Web サイトが立ち上げられて GitHub による Issue や PR の受付がされるようになった。

その後2018年初頭に両プロジェクトは「和解」し、LEDE の習慣も一部引き継ぎつつ再び OpenWrt へと統合されることになった。現在ではフォーラムもドキュメントもみてくれは OpenWrt.org ベースながら中身が刷新されている。

実際にやってみよう

さて、お手元にネットワークルーターはご用意いただけただろうか?

f:id:puhitaku:20181130013247j:plain

…いやいや、そういうガチなやつではない。もっとどこの家庭にでも普通にあるような…

f:id:puhitaku:20181130013326j:plain

そうそう、こういうのである。今回は、ハードオフで簡単に手に入りサクッとハックできるこちらの機種 Buffalo WHR-G301N を例に説明する。

中身を見る

早速分解していこう。

f:id:puhitaku:20181130015242j:plain

パカッと。

f:id:puhitaku:20181130015327j:plain

f:id:puhitaku:20181130020253j:plain

まず最初に飛び込んでくるのは、基板に居座る4つのICだ。上は無線PHY、真ん中は左からDRAM、CPU、SPI フラッシュとなっている。

  • CPU: Atheros AR7240 (MIPS 24Kc, 400 MHz)
  • DRAM: Samsung K4H561638N (256 Mb, 32 MiB)
  • Flash: Macronix MX25L3205D (32 Mb, 4 MiB)

そこそこの性能のルーターだ。DRAM が 32 MiB なので 16 MiB よりは戦える。Flash が 4 MiB しかないので厳しい。これから OpenWrt でビルドするファームはこの狭い 4 MiB のフラッシュに合わせて作ることになるが、この機種向けの設定が元から存在するため心配はいらない。

続いて SPI フラッシュの右を見ると、1x4 および 2x7 のいかにもピンヘッダがささりそうな穴がある。左が UART、右が JTAG のピンになっていて、ネットワークを介さずここから直接SoCとお話することができる。UART の利用については次回説明する。

OpenWrt ビルドの流れ

紹介する流れは以下の通りだが、公式の Quick Image Building Guide と大差ない。こちらも参照しながら作業することをおすすめする。

  1. 依存パッケージをインストールする
  2. git で OpenWrt を引っ張ってくる
  3. Software feed を引っ張ってくる
  4. OpenWrt の config を作る
  5. (任意)Linux の config を作る
  6. ビルドする
  7. 実機にインストールする

依存パッケージをインストールする

公式ガイドによると、2018年12月現在の Debian もしくは Ubuntu における依存パッケージのインストールコマンドは以下のとおり。

sudo apt-get install subversion g++ zlib1g-dev build-essential git python rsync man-db
sudo apt-get install libncurses5-dev gawk gettext unzip file libssl-dev wget zip time

筆者は Debian 10 (Buster, unstable) を使っているが特に問題なくインストールできた。

git で OpenWrt を引っ張ってくる

git clone https://git.openwrt.org/openwrt/openwrt.git

なお、GitHub のミラーもある。以前 LEDE がアクティブだった頃はこちらで Issue や PR の受付も全部やっていたので大変見やすかったのだが、今では PR を受け付けるのみになっている。

git clone https://github.com/openwrt/openwrt.git

安定版を使うのが安牌というやつである。チェックアウトしておこう。

$ git tag | grep 18
v18.06.0
v18.06.0-rc1
v18.06.0-rc2
v18.06.1
$ git checkout v18.06.1

Software feed を引っ張ってくる

Feed とは、ファームウェアにインストールされるパッケージをビルドしてインストールする Makefile の集合体である。apt update のように、リモートからパッケージの設定やビルドスクリプトを落としてくる。

cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a

実行して画面にいろいろ出た後に ./feeds の中を見てみると、カテゴライズされてソフトが並んでいるのがわかる。どんなものがあるかは次回触れることにする。

OpenWrt の config を作る

OpenWrt の menuconfig では、どのルーターに向けたビルドか、どのパッケージをインストールするかなどが選択できる。以下のコマンドを実行してみよう。

make menuconfig

f:id:puhitaku:20181204131331p:plain

Buffalo WHR-G301N に向けたビルドにするには、最低限以下を選択する:

  • Target System → Atheros AR7xxx/AR9xxx
  • Subtarget → Devices with small flash
  • Target Profile → Buffalo WHR-G301N

あとは Exit すればもうビルドの準備は完了だ。あとは make …とその前に、1つだけ Python 書き向けの注意点がある。

注意: Python 3 がシステムに存在する場合

pyenv を使わない / Python 3 がない / そもそも Python を書かない人の場合は、Python 2 をパッケージ管理ソフトで入れればOK。なのだが…

which python を実行すると Python 3 が真っ先に出るシステムでは、たいていビルドが失敗する。例えば筆者は以下のように普段 pyenv を使って python コマンドで Python 3 が起きてくるようにしている。

$ which python
/home/takumi/.pyenv/shims/python
 $ python -V
Python 3.7.1

OpenWrt のビルドシステムは現在 Python 2 を前提とした動作となっているため、PATH で最初に来る Python、すなわち which python と実行した時に出てくる Python は 2.7 でなければならない。

pyenv global system でシステム標準の Python (まだ Python 2 が大勢だろう)に切り替えて回避できたなら良いのだが、ルーターの設定を Web ブラウザ から変えられる LuCI のように pyenv が挟まったら死ぬパッケージもあるようだ。以下のような具合だ。

python /home/takumi/dev/router/openwrt_stable/build_dir/target-mips_24kc_musl/wireless-regdb-2017-10-20-4343d359/db2fw.py /home/takumi/dev/router/openwrt_stable/build_dir/target-mips_24kc_musl/wireless-regdb-2017-10-20-4343d359/regulatory.db /home/takumi/dev/router/openwrt_stable/build_dir/target-mips_24kc_musl/wireless-regdb-2017-10-20-4343d359/db.txt
/home/takumi/.pyenv/libexec/pyenv: line 145: /home/takumi/.pyenv/libexec/pyenv-exec: Argument list too long
make[3]: *** [Makefile:34: /home/takumi/dev/router/openwrt_stable/build_dir/target-mips_24kc_musl/wireless-regdb-2017-10-20-4343d359/.built] Error 126

呼び出しをフックしている pyenv-exec が死んでいるので、pyenv がactivateされていると避けようがない。筆者は pyenv あり/なしを切り替えて .bashrc を source できるようなコマンドを用意した。

if [ "$NOPYENV" = "" ]; then
    export PATH=$PATH:$HOME/.pyenv/bin:$HOME/.pyenv/shims
    eval "$(pyenv init -)"
else
    echo "Entering into NO PYENV mode."
fi

sourcerc() {
    if [ "$1" = "nopyenv" ]; then
        NOPYENV=1 source $HOME/.bashrc
    elif [ "$1" = "" ]; then
        source $HOME/.bashrc
    else
        echo "Usage: sourcerc [nopyenv]"
    fi
}

(任意)Linux の config を作る

make kernel_menuconfig を実行すると Linux の config を直に操作できる。ただ、例えば Filesystem や HID のドライバのようなよく使われる Kernel Module は OpenWrt 側の make menuconfig から Enable できるので、理由がない限り使わなくてよい。

ビルドする

よっしゃ!いよいよ make するで!

CPUの数に合わせて -j オプションを指定するとビルドが並列化されるため強くおすすめする。筆者は6コア/12スレッドのCPUを使っているので -j12 を指定した。

make -j12

よくこういう時に「コーヒーでも飲んで待とう」とか書かれることがある。手でドリップして悠長に飲むなら別だが、普通はコーヒーを1杯飲んだ程度では終わらないので、別の作業でもしながら気長に待とう。

次回予告

今回はここまで。次回はビルドしたバイナリの流し込みや、ファームのカスタマイズ、ハードウェアの初歩的な改造について解説する。

脚注