NSB-3NR1T1MLVをLinux箱として使う (Buildroot でツールチェーン構築 & TFTP ブート)

# はじめに

私が最初に NSB-3NR1T1MLV を購入してから半年になりました。 Linux 箱化計画をさぼっている間に NSB-3NRV 界隈では「ファームウェア GPL ソースコード公開」「 NTT-X Store の投げ売り在庫がついに無くなる」という二大事件が発生。すっかり旬を過ぎた感がありますが、計画はまだ続きます。

さて、今回は本製品を Linux 箱にする前段階として、クロスコンパイル用のツールチェーンを作り、 Busybox だけ入ったルートファイルシステム (initramfs) を構築して TFTP ブートしてみました。 

ツールチェーンとルートファイルシステムの作成には Buildroot を使いました。この記事の半分ぐらいは Buildroot の使い方をなぞっただけです。
TFTP ブートは、試験用のカーネルやルートファイルシステムを読み込ませるために使います。そうすれば製品版ファームウェアが使っている Flash や HDD を汚さずに済むからです。

# 準備

1. NSB-3NR1T1MLV (本体)
ファームウェアを 1.08 にアップデートしました。

1. CISCO準拠のシリアルケーブル
先端がRJ-45になっているシリアルケーブルです。私はUSB接続のものを買いました。

1. ターミナルエミュレータ
シリアル通信ができるもの。Tera Term とか PuTTY とか RLogin とかお好みでどうぞ。 115200 bps で通信できます。

1. Linux PC
Buildroot の構築用と TFTP サーバとして使用します。仮想マシンでよいです。私は VMWare 上の Ubuntu 18.04 で作業しました。



# Buildroot の入手

https://buildroot.org/ からダウンロードしてきます。
最新版ではなく、かなり古い buildroot-2014.05 を選びました。これは本製品のファームウェアで使われている uClibc 0.93.2 をサポートする最終版にあたります。

# Buileroot の設定

buildroot を展開し、 `$ make menuconfig` で設定していきます。
config ファイルは [こちら](https://github.com/ac100v/nsb-3nrv_examples/blob/master/buildroot-2014.05.config/config.nsb3nrv) に置いてあります。

## クロスコンパイラ

本製品のファームウェアの実行ファイルと `readelf -A` の結果がなるべく近くなるように設定値を調整しました。

### Target Options

```
  │ ┌─────────────────────────────────────────────────────────────────────┐ │  
  │ │        Target Architecture (ARM (little endian))  --->              │ │  
  │ │        Target Architecture Variant (cortex-A9)  --->                │ │  
  │ │        Target ABI (EABI)  --->                                      │ │  
  │ │    [*] Enable NEON SIMD extension support                           │ │  
  │ │        Floating point strategy (NEON)  --->                         │ │  
  │ │        ARM instruction set (ARM)  --->                              │ │  
  │ └─────────────────────────────────────────────────────────────────────┘ │  
```

### Build Options

変更不要。

### Toolchain

```
  │ ┌─────────────────────────────────────────────────────────────────────┐ │  
  │ │        Toolchain type (Buildroot toolchain)  --->                   │ │  
  │ │    (nsb3nrv) custom toolchain vendor name                           │ │ 
  │ │        *** Kernel Header Options ***                                │ │  
  │ │        Kernel Headers (Linux 3.4.x kernel headers)  --->            │ │  
  │ │        C library (uClibc)  --->                                     │ │  
  │ │        *** uClibc Options ***                                       │ │  
  │ │        uClibc C library Version (uClibc 0.9.32.x)  --->             │ │  
  │ │    (package/uclibc/uClibc-0.9.32.config) uClibc configuration file t│ │  
  │ │    [ ] Enable large file (files > 2 GB) support                     │ │  
  │ │    [ ] Enable IPv6 support                                          │ │  
  │ │    [ ] Enable RPC support                                           │ │  
  │ │    [ ] Enable WCHAR support                                         │ │  
  │ │    [ ] Enable toolchain locale/i18n support                         │ │  
  │ │        Thread library implementation (Native POSIX Threading (NPTL))│ │  
  │ │    [ ] Thread library debugging                                     │ │  
  │ │    [ ] Enable stack protection support                              │ │  
  │ │    [*] Compile and install uClibc utilities                         │ │  
  │ │    [ ] Compile and install uClibc tests                             │ │  
  │ │        *** Binutils Options ***                                     │ │  
  │ │        Binutils Version (binutils 2.20.1)  --->                     │ │  
  │ │    ()  Additional binutils options                                  │ │  
  │ │        *** GCC Options ***                                          │ │  
  │ │        GCC compiler Version (gcc 4.8.x)  --->                       │ │  
  │ │    ()  Additional gcc options                                       │ │  
  │ │    [ ] Enable C++ support                                           │ │  
  │ │    [*] Enable compiler tls support                                  │ │  
  │ │    [ ] Enable compiler OpenMP support                               │ │  
  │ │    [ ] Enable libmudflap support                                    │ │  
  │ │    [ ] Enable elf2flt support?                                      │ │  
  │ │    [ ] Build cross gdb for the host                                 │ │  
  │ │    [ ] Purge unwanted locales                                       │ │  
  │ │    ()  Generate locale data                                         │ │  
  │ │    [*] Enable MMU support                                           │ │  
  │ │    (-pipe) Target Optimizations                                     │ │  
  │ │    ()  Target linker options                                        │ │  
  │ │    [ ] Register toolchain within Eclipse Buildroot plug-in          │ │  
  │ └─────────────────────────────────────────────────────────────────────┘ │  
```

## ルートファイルシステム

### Target packages

初期状態では Busybox だけです。
用途に合わせてさらにパッケージを追加できますが、初回は何も追加しなくてもよいでしょう。

### Filesystem images

```
  │ ┌─────────────────────────────────────────────────────────────────────┐ │  
  │ │    [ ] cloop root filesystem for the target device                  │ │  
  │ │    [*] cpio the root filesystem (for use as an initial RAM filesyste│ │  
  │ │          Compression method (gzip)  --->                            │ │  
  │ │    [*]   Create U-Boot image of the root filesystem                 │ │  
  │ │    [ ] cramfs root filesystem                                       │ │  
  │ │    [ ] ext2/3/4 root filesystem                                     │ │  
  │ │        *** initramfs needs a Linux kernel to be built ***           │ │  
  │ │    [ ] jffs2 root filesystem                                        │ │  
  │ │    [ ] romfs root filesystem                                        │ │  
  │ │    [ ] squashfs root filesystem                                     │ │  
  │ │    [*] tar the root filesystem                                      │ │  
  │ │          Compression method (no compression)  --->                  │ │  
  │ │    ()    other random options to pass to tar                        │ │  
  │ │    [ ] ubifs root filesystem                                        │ │  
  │ │    [ ] yaffs2 root filesystem                                       │ │  
  │ └─────────────────────────────────────────────────────────────────────┘ │  
```

# ツールチェーン・ルートファイルシステムの構築

`$ make`
これだけです。あとは、 Buildroot が勝手にソースコードをダウンロード・ビルドしてくれるのを待つだけ。とても簡単。

ツールチェーンが `output/host/usr/bin` に生成されるのでパスを通しておきましょう。
ルートファイルシステムは `output/images/rootfs.cpio.uboot` に出来上がります。こちらは TFTP サーバ管理下のフォルダにコピー。ちなみに、 Ubuntu 18.04 の TFTP フォルダは `/srv/tftp/` でした。

# TFTP ブート

まだカーネルのビルドは行っていないので製品版カーネルを Flash からロードし、ルートファイルシステムは TFTP からロードして起動してみます。

本製品の u-boot は TFTP に対応しています。ただし、本製品で通常使用する eth0 (INTERNET) ではなく、 eth1 (LAN1 ～ LAN3 のどれか) を TFTP サーバと接続してください。

電源投入して、シリアルコンソールの "Hit any key to stop autoboot" のカウントが0になる前に何かキーを押すと "U-BOOT # " とプロンプトが表示されます。以下のように入力。

```
U-BOOT # setenv ipaddr 192.168.0.20      ← NASのIPアドレス
U-BOOT # setenv serverip 192.168.0.10    ← TFTPサーバのIPアドレス
U-BOOT # nboot 0x2100000 0 0x00C00000    ← ※ 最後の引数は要注意
U-BOOT # tftpboot 0x10000000 rootfs.cpio.uboot
U-BOOT # bootm 0x2100000 0x10000000
```
※ nboot コマンドの最後の引数は、 Linux カーネルが格納されている NAND Flash のアドレスです。ファームウェアをアップデートするとアドレスが変わるようです。u-boot で `printenv bootcmd` と入力したとき表示される値と同じにしてください。私の環境ではこのようになりました。

```
U-BOOT # printenv bootcmd
bootcmd=nboot 0x2100000 0 0x00C00000; bootm
```

アドレスを間違えるなどして NAS がハングアップしてしまったら電源プラグを抜いてやり直し。
うまくいけば 10 秒程度でログインプロンプトが表示されるはずです。

```
Welcome to Buildroot
buildroot login: 
```

Buildroot で特に設定していなければ、パスワード無しで root ログインできます。
初期状態では Busybox しか入っていません。ひととおり起動確認できたら、 Buildroot でルートファイルシステムにパッケージを追加して遊んでみるとよいと思います。SMB2 対応した Samba をインストールして Windows 10 でも使える NAS に仕立てるとか。

# まとめ

* ツールチェーンとルートファイルシステムを Buildroot で作成しました。
* NSB-3NR1T1MLV の u-boot は TFTP 対応です。 Buildroot のルートファイルシステムも起動できました。
* 組み込み Linux 開発環境構築ツールとして Buildroot はとても簡単。とにかく使ってみて。

# 今後の予定

* Linux カスタムカーネルビルド
* HDD アクセス時に LED を点滅させる
* Debian インストール