NanoPi NEOのルートファイルシステムをBuildrootで作る(1)

#始めに
NanoPi NEOではオフィシャルの起動SDカードではubuntu 16.04のルートファイルシステムが入っています。手軽に実験するときには必要ものはaptコマンドでインストールできるので便利です。
しかし、いろいろなデーモンプロセスが動いていたりして多少冗長な部分があります。

コンパクトなルートファイルシステムを作るときには私はいつもBuildrootを使います。今回はNanoPi NEOでそれをやってみます。

#Buildrootとは

https://buildroot.org/

私の記憶では元々はuclibcというlibcの軽量版のルートファイルシステムを構築するものだったのですが、今はglibcも選択できるようになっています。

メインのコマンド群にはbusyboxを使用します。
追加できるパッケージはかなり種類が多く、必要となるものはだいたい揃います。

ビルドのコンフィグの設定にはLinuxカーネルのビルドのときと同じようなmenuconfig を使います。

クロスコンパイラやルートファイルシステムを構築に必要なホスト側のツールは全て自前でソースコードからビルドします。自己完結的です。このためホストの環境の変化の影響を受けにくいです。組み込み機器の製品ではロングセラーになると5年以上もメンテナンスをすることもあると思いますが、そのときにホストのOSをバージョンアップしても大丈夫なのは地味にポイントが高いです。



#Buildrootのインストール
今回のビルドはUbuntu 16.04 で行っています。

```
wget https://buildroot.org/downloads/buildroot-2017.11.2.tar.bz2
tar xf buildroot-2017.11.2.tar.bz2 
cd buildroot-2017.11.2/
```

```
sudo apt install build-essential libncursesw5-dev unzip bc zlib1g-dev
```


#NanoPi NEO向けのビルド

NanoPi NEO向けにはすでに用意されているものがあるので、それに沿ってビルドします。

```board/friendlyarm/nanopi-neo/readme.txt 
Intro
=====

The instructions herein are valid for the FriendlyARM NanoPi NEO,
both the 256MiB and 512MiB versions. They should also work for the
NanoPi NEO Air, but this is untested so far.

The FriendlyARM Nanopi NEO is a 4x4cm² board with an Allwiner H3 SoC:
  - quad-core Cortex-A7 @1.2GHz
  - 256 or 512MiB of DDR
  - uSDCard as only storage option
  - 3x USB 2.0 host (one socket, two on expansion pin-holes)
  - 1x USB 2.0 OTG (also used as power source)
  - 10/100 ethernet MAC
  - GPIOs, SPI, I2c...

Support for the Nanopi NEO in U-Boot and Linux is very recent, so only
core, basic features are available.

Unfortunately, support for the ethernet MAC and the USB OTG are not
yet upstream, but are being actively worked on.


How to build
============

    $ make nanopi_neo_defconfig
    $ make

Note: you will need access to the internet to download the required
sources.

You will then obtain an image ready to be written to your micro SDcard:

    $ dd if=output/images/sdcard.img of=/dev/sdX bs=1M

Notes:
  - replace 'sdX' with the actual device with your micro SDcard,
  - you may need to be root to do that (use 'sudo').

Insert the micro SDcard in your NanoPi NEO and power it up. The console
is on the serial line, 115200 8N1.
```

用意されている nanopi_neo_defconfig でビルドします。

```
make nanopi_neo_defconfig
make menuconfig
```
おそらくこの先何度もビルドを繰り返すことになると思うので、ccache を有効にしておきます。2回目以降のビルドの時間が格段に短縮できるのでおすすめです。しかもccacheの入手やインスールも全てBuildrootのシステムがやってくれます。

make menuconfig の"Build options" のメニュー中の　"Enable compiler cache" をONにします。
詳しくは以下のページを参照。
https://buildroot.org/downloads/manual/manual.html#ccache


ビルドには時間がかかるので、sshのセッションが切れてもよいように、nohupコマンド経由でmakeを実行します。ビルドのログはnohup.outというファイルに追記されます。

```
nohup make &
tail -f nohup.out
```
make に-jオプションはつけてはいけません。デフォルトで(CPUの個数+1)の並列ビルドを行ってくれます。明示的にビルドのジョブ数を指定したいときはmenuconfig の中で指定します。

ビルドの生成物は以下の通り。

```
$ ls -lh output/images/
total 53M
-rw-r--r-- 1 koba koba  299 Feb 10 07:41 boot.scr
-rw-r--r-- 1 koba koba  10M Feb 10 07:41 boot.vfat
-rw-r--r-- 1 koba koba  32M Feb 10 07:41 rootfs.ext2
lrwxrwxrwx 1 koba koba   11 Feb 10 07:41 rootfs.ext4 -> rootfs.ext2
-rw-r--r-- 1 koba koba  43M Feb 10 07:41 sdcard.img
-rw-r--r-- 1 koba koba  14K Feb 10 07:40 sun8i-h3-nanopi-neo.dtb
-rw-r--r-- 1 koba koba 381K Feb 10 07:39 u-boot.bin
-rw-r--r-- 1 koba koba 413K Feb 10 07:39 u-boot-sunxi-with-spl.bin
-rw-r--r-- 1 koba koba 3.5M Feb 10 07:40 zImage
```

この中の sdcard.img をddコマンドでマイクロSDカードに書き込みます。
u-bootもkernelも含めて全てソースコードからビルドしてくれます。make一発ですむのが楽です。

#起動してみる

ブートログはgistに貼りました。
https://gist.github.com/tetsu-koba/4b537ef9866d331fa01e740567c79878
カーネルはメインラインのツリーの 4.10.1　です。

psコマンドを実行して、カーネルスレッドをのぞいたものは以下の通りです。たったこれだけのデーモンしか動いていません！素朴。必要なものはここから追加していくことになります。

```
# ps |grep -v '\['
PID   USER     COMMAND
    1 root     init
   75 root     /sbin/syslogd -n
   78 root     /sbin/klogd -n
   98 root     -sh
  108 root     ps
# 
```
ディスクの使用量は以下の通り。たったの1.8MB。小さい！

```
# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                27.0M      1.8M     23.0M   7% /
devtmpfs                249.4M         0    249.4M   0% /dev
tmpfs                   249.9M         0    249.9M   0% /dev/shm
tmpfs                   249.9M     20.0K    249.8M   0% /tmp
tmpfs                   249.9M     16.0K    249.8M   0% /run
# 
```

#次は

さて、起動したのはよいのですがこの構成だとeth0のMACアドレスが起動するたびに異なるランダム値になります。MACアドレスの扱いがまだメインラインにマージされていないためです。

今回は個体の識別をMACアドレスで行いたいので、メインラインのカーネルでなくてベンダーツリーのカーネルに変更することにします。それなりに苦労しました。それは次の記事で。
[NanoPi NEOのルートファイルシステムをBuildrootで作る(2)](https://qiita.com/tetsu_koba/items/de925c3d8a011e5eb8ff)