Buildroot の使い方 - 基本編

Buildroot とは
==============

Buildroot は組込み Linux システムの構築を自動化できるシステムです。

公式サイトは[こちら](https://buildroot.org/)です。

Buildroot を使うと主に以下のものが自動的に構築できます。

- クロスコンパイル Toolchain
- Busybox
- ルートファイルシステム
- Linux Kernel
- ブートローダ

この中では特にルートファイルシステムが自動的に構築できるのが嬉しいですね。
あれを全部手動でやれと言われたら結構しんどいです。
Kernelやブートローダはターゲットによっていろいろ差異があるので個別に対応することが多いかと思います。

Buildroot にはとても整理された公式ドキュメントがこちらにあります。
[Buildroot Documentation](https://buildroot.org/docs.html)

しかし、毎回英語のドキュメントを読むのがしんどいので、かみ砕いた使用方法等を記載することにしました。
まず、今回は基本的な使用方法を説明します。
その後、少なくとも br2-external の使い方ぐらいまでは書く予定です。

Buildroot 基本編
==================

ターゲットとして Raspberry Pi 3 を使用して Buildroot の基本的な使用方法を説明します。
ビルド環境は VMware Player 上の Ubuntu 17.10 です。

## Buildroot の入手

今回は **Latest long term support release: 2017.02.9** を使用します。

[Download](https://buildroot.org/download.html)ページから以下のファイルをダウンロードします。

- buildroot-2017.02.9.tar.bz2

tar.gz 形式よりも tar.bz2 形式の方が圧縮率が高くファイルサイズが小さいのでダウンロード時間が短く済みます。

## 環境の確認

Buildroot を使用するために必要なパッケージがいくつかあります。
ここには細かくマニュアルの [Chapter 2. System requirements](https://buildroot.org/downloads/manual/manual.html#requirement) を参照して確認します。

## ビルド手順

Buildroot のマニュアルにも **Important:** と強調して記載されていますが、Buildroot による作業は基本的にノーマルユーザで実行します。
root権限は不要です。

ダウンロードした buildroot-2017.02.9.tar.bz2 を展開します。

```
$ tar xjvf buildroot-2017.02.9.tar.bz2
```

展開した buildroot ディレクトリに入ります。

```
$ cd buildroot-2017.02.9/
```

Buildroot では Linux Kernel のように `make menuconfig` 等を使用して設定を行います。

ここからターゲットの環境に合わせて設定を行うわけですが、メジャなターゲットの場合デフォルトの設定が用意されている場合があります。
以下のコマンドを実行すると用意されているデフォルト設定の一覧が表示されます。

```
$ make list-defconfigs
```

表示される一覧の中に Raspberry Pi 用のものが見えますね。

```
  raspberrypi0_defconfig              - Build for raspberrypi0
  raspberrypi2_defconfig              - Build for raspberrypi2
  raspberrypi3_defconfig              - Build for raspberrypi3
  raspberrypi_defconfig               - Build for raspberrypi
```

defconfig の実体は **configs/** 以下に置かれています。

## Raspberry Pi 3 用イメージのビルド

Raspberry Pi 3 用のイメージをビルドする際は **raspberrypi3_defconfig** を使用します。

まず以下のコマンドを実行します。

```
$ make raspberrypi3_defconfig
```

これで Raspberry Pi 3 用のデフォルト設定が読み込まれてその内容が **.config** に書き込まれます。

ここで `make menuconfig` を実行します。

```
$ make menuconfig
```

`Target Options --->` に入ると Target Architecture に ARM が選択されていたりと Raspberry Pi 3 の設定になっていることがわかります。


とりあえず何も変更せずに [Exit] を選択して抜けます。
そして make を実行。

```
$ make
```

初回実行時は各パッケージのダウンロードを行うためかなり時間がかかるので余裕を持って実行する必要があります。
ネットワーク環境やPCスペックによりますが1時間前後は覚悟しておいた方がいいかもしれません。

ビルドが完了すると **output/images/** に **sdcard.img** が作成されます。
これが Raspberry Pi 3 用のイメージです。

## SDカードへの書込み

USBカードリーダ等でSDカードを挿入すると **/dev/sdb** 等で認識します。
`dmesg` の出力を見ることでどのように認識しているか確認できます。

私の環境では以下のように **/dev/sdb** として認識していることがわかります。

```
[ 3230.165889] usb 3-2: new high-speed USB device number 5 using xhci_hcd
[ 3230.472351] usb 3-2: New USB device found, idVendor=05e3, idProduct=0749
[ 3230.472356] usb 3-2: New USB device strings: Mfr=3, Product=4, SerialNumber=2
[ 3230.472359] usb 3-2: Product: USB3.0 Card Reader
[ 3230.472361] usb 3-2: Manufacturer: Generic
[ 3230.472363] usb 3-2: SerialNumber: 000000001532
[ 3230.683088] usb-storage 3-2:1.0: USB Mass Storage device detected
[ 3230.683695] scsi host33: usb-storage 3-2:1.0
[ 3230.683820] usbcore: registered new interface driver usb-storage
[ 3230.703857] usbcore: registered new interface driver uas
[ 3231.697365] scsi 33:0:0:0: Direct-Access     Generic  STORAGE DEVICE   1532 PQ: 0 ANSI: 6
[ 3231.698596] sd 33:0:0:0: Attached scsi generic sg2 type 0
[ 3231.978129] sd 33:0:0:0: [sdb] 30253056 512-byte logical blocks: (15.5 GB/14.4 GiB)
[ 3231.981665] sd 33:0:0:0: [sdb] Write Protect is off
[ 3231.981669] sd 33:0:0:0: [sdb] Mode Sense: 21 00 00 00
[ 3231.984512] sd 33:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[ 3231.995999]  sdb: sdb1 sdb2
[ 3232.001909] sd 33:0:0:0: [sdb] Attached SCSI removable disk
[ 3232.670573] EXT4-fs (sdb2): mounted filesystem with ordered data mode. Opts: (null)
```

SDカードにフォーマットされたパーティションが存在すると Ubuntu 等では自動的にマウントされてしまう場合があるため、イメージを書込む前にアンマウントしておきます。

**/dev/sdb** と認識している場合以下のようにしてマウントされているかどうかを確認します。

```
$ mount | grep sdb
/dev/sdb1 on /media/<username>/1C09-6C2B type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)
/dev/sdb2 on /media/<username>/bf3c9980-445e-46a2-bcd4-de9127ee8ce8 type ext4 (rw,nosuid,nodev,relatime,errors=remount-ro,data=ordered,uhelper=udisks2)
```

それぞれ `umount` コマンドでアンマウントしておきます。

```
$ umount /dev/sdb1
$ umount /dev/sdb2
```


ここに先程作成した sdcard.img を書込みます。

```
$ sudo dd bs=4M if=./output/images/sdcard.img of=/dev/sdb conv=fsync
```

参考：[RaspberryPi 公式のマニュアル] (https://www.raspberrypi.org/documentation/installation/installing-images/linux.md) 

書込みが終わったSDカードを Raspberry Pi 3 に挿入して電源を入れると Linux が起動するはずです。
起動ログがダーッと流れたあと `Buildroot login:` というプロンプトが表示されます。
ここで `root` と入力して Enter キーを押すとログインできます。

基本編はこれで終了です。