Raspberry Pi 2 に BTRFS な Arch Linux ARM を入れた

# はじめに

Raspberry Pi 2 に Arch Linux ARM (alarm) をインストールしたのでそのメモ。
Arch Linux ARM の[公式ページ](http://archlinuxarm.org/platforms/armv7/broadcom/raspberry-pi-2)にある方法だとファイルシステムが ext4 になってしまうが、頑張って btrfs でインストールしてみた。

ちなみに、インストールのために Raspberry Pi 用にキーボードやディスプレイは不要。


# インストール用マシンの準備

SD カードに対していろいろするためのマシンを用意する。
基本的にはインストール用マシンで OS のインストールからセットアップまで全ての作業を行う。

## alarm のバイナリをダウンロードしておく

公式のダウロードページから Raspberry Pi 2 用のバイナリを入手する。
[Downloads | Arch Linux ARM](http://archlinuxarm.org/developers/downloads)
ARMv7 Raspberry Pi 2 という項目があるはずなのでそこの tar.gz をダウンロードしておく。
結構時間がかかるのでその間に次の作業に移る。

## インストール作業に必要なパッケージのインストール

具体的には下記のようなパッケージをインストールしておく。

* btrfs-progs
* arch-install-script
* qemu
* qemu-user-static (AUR)
* binfmt-support (AUR)

btrfs-progs は btrfs の操作に必要。
arch-install-script は Arch Linux 用の `chroot` である `arch-chroot` コマンドが使えるようになるもの。
qemu、qemu-user-static、binfmt-support は詳細は後述するが `chroot` するために必要。

## SD カードを差し込む

SD カードを何かしらの手段で読む。自分は VAIO のノートだったので最初から SD カードスロットがあった。
`lsblk` を実行してみてデバイスとしてちゃんと認識しているか確認する。

```console
# lsblk -f
sda
├─sda1      ...
├─sda2      ...
└─sda3      ...
mmcblk0
```

上記のように `mmcblk0` のようなデバイスがあれば OK。(名前はこれで固定なのかは不明)


# パーティションの作成

まずは `cfdisk` を使ってパーティションを切る。
最初にパーティションタイプを聞かれたら `DOS` を選択する。
下記のような感じで3つほどパーティションを作成する

|Device|Size|Type|
|:----:|:--:|:--:|
|/dev/mmcblk0p1|100MB 程度|W95 FAT32|
|/dev/mmcblk0p2|512MB 程度|Linux swap|
|/dev/mmcblk0p3|たくさん|Linux filesystem|

スワップファイルにせず、わざわざスワップパーティションを作成するのは btrfs がスワップファイルに対応していないから。


# ファイルシステムの作成

下記のような感じでファイルシステムを作る。
スワップパーティションに対してもスワップを有効にしておく。

```console
# mkfs.vfat /dev/mmcblk0p1
# mkfs.btrfs /dev/mmcblk0p3

# mkswap /dev/mmcblk0p2
# swapon /dev/mmcblk0p2
```

btrfs は root 用と home 用のサブボリュームを作ることにする。そのために一時的にマウントする。

```console
# mkdir /mnt/sdcard
# mount /dev/mmcblk0p3 /mnt/sdcard
# cd /mnt/sdcard
# btrfs subvolume create rpi2-root
# btrfs subvolume create rpi2-home
```

下記のコマンドでサブボリュームの ID を確認しておく。

```console
# btrfs subvol list -p .
ID 257 gen 50449 parent 5 top level 5 path rpi2-root
ID 258 gen 50437 parent 5 top level 5 path rpi2-home
```

root 用のパーティションをデフォルトのサブボリューム ID に設定する。

```console
# btrfs subvolume set-default 257 .
```

作業が終わったらアンマウントする。

```console
# umount /dev/mmcblk0p3
```


# ファイルのコピー

最初にマウントをする。

```console
# mount /dev/mmcblk0p3 /mnt/sdcard
# mkdir /mnt/sdcard/boot
# mount /dev/mmcblk0p1 /mnt/sdcard/boot
# mkdir /mnt/sdcard/home
# mount /dev/mmcblk0p3 -osubvol=rpi2-home /mnt/sdcard/home
```

`mmcblk0p3` を2回マウントしているが、最初の方はデフォルトのサブボリュームである root になっている。
2回目の方は `subvol` を指定しているので home の方のパーティションがマウントされる。


最初にダウンロードしておいたバイナリを SD カードにコピーする。

```console
# bsdtar -xpf ArchLinuxARM-rpi-2-latest.tar.gz -C /mnt/sdcard
```

# fstab

忘れずに fstab を生成しておく。(SD カード側に)最初から存在する `/etc/fstab` は上書きしても問題なさそう。

```console
# genfstab -U /mnt/sdcard > /mnt/sdcard/etc/fstab
# vim /mnt/sdcard/etc/fstab
```

fstab の中身は基本的にはそのままで良いはずだが、インストール用マシン側の設定が混じったりすることもあるのでちゃんと見ておく。
btrfs の subvol などが正しく設定されているかも一応確認する。



# chroot

Raspberry Pi が動作する環境はバイナリが arm なので、通常の Arch Linux のインストールのように SD カードに `chroot` することができない。
しかし、QEMU を使って実行ファイルを x86 に変換することで arm の環境であっても `chroot` させることができるようになる。

まずは ARM から x86 への変換を有効にする。

```console
# update-binfmts --enable qemu-arm

結果を確認
# update-binfmts --display qemu-arm
qemu-arm (enabled):
     package = qemu-user-static
     ...
```

ARM からの変換を行う実行ファイルを SD カードにコピーする。

```console
# cp /usr/bin/qemu-arm-static /mnt/sdcard/usr/bin
```

これで問題なく `chroot` できるようになったはず。

```console
# arch-chroot /mnt/sdcard /bin/bash
```

アーキテクチャが正しく ARM になっていることを確認する。

```console
# uname -m
armv7l
```

# boot 関係

地味に大切なステップ。
デフォルトは ext4 でブートするようになっているのでそのあたりの設定を変える必要があるのだが、それは `/boot/cmdline.txt` に書かれたカーネルのパラメータで指定されているので
そこをちょろっと書き換えてやれば良い。

```sh:/boot/cmdline.txt
# root パラメータのデフォルトは /dev/mmcblk0p2 になっているので3に書き換える。
# rootfstype というパラメータを追加する。
root=/dev/mmcblk0p3 rootfstype=btrfs rw rootwait ...
```

initrd の再作成が必要な気がしていたが別にそんなことはなかったぜ！

# もろもろセットアップ

あとはいつも通り。

* ミラー `/etc/pacman.d/mirrorlist` を編集して、台湾あたりを先頭に持ってくる。
* `pacman -Syyu` でシステムのアップデート。
* `pacman -S base-devel` でいろいろインストール。
* `/etc/vconsole.conf` でキーボードレイアウトとコンソールフォントを指定。
* タイムゾーン。
* ユーザの追加。
* ホスト名。
* ほか必要なもの。


chroot 環境では当然 CPU はインストール側マシンのものを使うので、ビルドに時間がかかるものなどは一通りインストールしておくとよい。


# 起動！

SD カードを抜いて Raspberry Pi 2 に挿して電源を入れれば起動するはず！

```console
# exit
chroot から脱出
# umount -R /mnt/sdcard
SD カードを抜く
```