archLinuxをインストールしてみた。

# はじめに

OSの勉強とドキュメントの練習のために、[ArchWiki][archwiki]のインストールガイドを参考にVMwareにインストールしてみました。


なお、GUIの設定までは触れていません。

[archwiki]:https://wiki.archlinux.jp/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89

## 環境
- VMware Workstation 15 Player
- CPU
  - AMD ryzen 5
- 仮想マシンのコア数 
  - 1
- 仮想マシンのメモリ
  - 768 MB
- ハードディスク
  - 8 GB


## 起動する前に

UEFIブートしたいので、作成したvmxファイルに以下の１行を追加しました。

```
firmware = "efi"
```

# 仮想マシン起動後

## キーボードの設定

入力ミスが怖いので、まずはじめにキーボードを設定しました。

```bash
loadkeys jp106
```


## 時刻の設定

```bash 
timedatectl set-ntp true
```


## 起動モードの確認

起動モードが`BIOS`か`UEFI`によって、推奨されているパーティションの形式(`MBR`形式か`GPT`形式)が変わるので、確認しておきました。

```bash
ls /sys/firmware/efi/efivars
```

- ディレクトリが存在すれば`UEFI`で起動しているので、GPT形式が推奨です。
  - `gdisk`でパーティショニングします。
- 存在しなければ`BIOS`で起動しているので、MBR形式が推奨です。
  - `fdisk`でパーティショニングします。


# インストールの設定

## インストールまでのアウトライン

1. パーティションテーブルの作成
2. パーティションの作成
3. ファイルシステムの作成
4. パーティションのマウント
5. ベースシステムのインストール
   1. パーティションのマウント
   2. ミラーの変更
   3. インストール

## 1. パーティションテーブルの作成

GPT形式でパーティショニングしました。
まず、`gdisk`を実行し、対話モードに入りました。

```bash
gdisk /dev/sda
```

`o`コマンドで、新しいパーティションテーブルを作成しました。


### ※gdisk内のコマンド一覧(一部)

主に使うコマンドだけ記載しておきます。詳しく知りたい場合は、マニュアルを閲覧すると良いでしょう。

- `?`でコマンドの一覧を表示します。
- `o`で新しいパーティションテーブルを作成します。
- `n`でパーティションの追加します。
- `w`でパーティションテーブルの変更を保存して終了します。
- `q`で保存せずに終了します。



## 2. パーティションの作成

次に`n`コマンドで、パーティションを作成しました。


なお、Arch Linux をインストールするデバイスには以下のパーティションが必要です。

- UEFI が有効になっている場合、EFI システムパーティション。
- ルートディレクトリ / のパーティション。


次の通りにパーティションを二つ作成しました。


### 今回のパーティションの仕様

|パーティション|パーティション番号|先端位置|終端位置|パーティション・タイプ|
|---|---|---|---|---|
|ESP|デフォルト|デフォルト|+512M|ef00 EFI System|
|ルートディレクトリ (/) |デフォルト|デフォルト|デフォルト|8304 Linux x86-64 root (/)|


もともとあったパーティションを上書きしたときは、OSに認識されない場合があります。その際は、再起動するか`parprobe /dev/sda`をして、OSにパーティション・テーブルが変更されたことを知らせてください。



パーティション作成後、`w`コマンドで変更を保存し、対話モードを終了しました。


## 3. ファイルシステムの作成(パーティションのフォーマット)

`lsblk -f`で確認したところ、パーティションを作ったばかりの段階では、ファイルシステムもUUIDも設定されていませんでした。


ESP用のパーティション`/dev/sda1`も`FAT32`にフォーマットしました。

```bash
# EFIシステムパーティション FAT32
mkfs.fat -F32 /dev/sda1
```


ルートディレクトリ用のパーティション`/dev/sda2`を`ext4`にフォーマットしました。

```bash
# ルートディレクトリ ext4
mkfs.ext4 /dev/sda2
```



## 4. パーティションのマウント

ルートディレクトリ(/)のマウントは次の通りに行いました。

```bash
mount -t ext4 \
    -o defaults,noatime,nodiratime \
    /dev/sda2 /mnt
```


ESPのほうは、今回はバインドマウントで行いました。

まず、`/mnt/esp`ディレクトリを作り、ここに`/dev/sda1`を普通にマウントしました。それから`/mnt/boot`にバインドマウントをしました。


```bash
# マウントポイントの作成
mkdir -p /mnt/boot /mnt/esp/

# 通常のマウント
mount -t vfat \
    -o defaults \
    /dev/sda1 /mnt/esp

# バインドマウント
mount --bind /mnt/esp /mnt/boot
```


## 5. ベースシステムのインストール


### ミラーの変更

初期のミラーではインストールの速度が非常に遅いので、`/etc/pacman.d/mirrorlist`を編集してミラーを変更します。

私の場合は、国外も含めてすべてのサーバがアンコメントされていましたので、まずはじめに全てコメントアウトしました。その後、日本のサーバだけを選んでアンコメントしました。


```bash
# すべてのサーバをコメントアウトする。
sed -i -e "s/Server/#Server/g" /etc/pacman.d/mirrorlist

# vim で使いたいミラーサーバをアンコメント。
vim /etc/pacman.d/mirrorlist
```


### インストール

`base`と`base-devel`以外は環境と都合に合わせて追加しましょう。

私の場合は、設定ファイルの編集のために`vim`を、AMDのCPUを使っているために`amd-ucode`を、合わせてインストールしました。

```bash
pacstrap /mnt base base-devel vim amd-ucode
```

# システムの設定

## システムの設定のアウトライン

1. fstabの生成
2. chroot
3. 基本的なシステム設定
   - タイムゾーン
   - ロケール
   - コンソールキーマップ
   - ホストネーム
4. ネットワーク設定
5. Initramfs
6. ブートローダ


### ビープ音の無効化

うるさいので、一時的に無効化しておきました。

```bash
rmmod pcspkr
```


## fstabの生成

```bash
genfstab -U /mnt >> /mnt/etc/fstab
```

`genfstab`コマンドは、バインドマウントと普通のマウントを区別しないようなので、このとき`/dev/sda1`のエントリがそっくり二つできてしまいました。違いはマウントポイントのみです。
`/boot`のほうのエントリを`vim`で次のように編集しました。

```:/etc/fstab
/esp /boot none defaults,bind 0 0
```

ファイルシステム名の`none`は、バインドマウントかマウントの移動の際に使用する項目のようです。


## 2. chroot

```bash
arch-chroot /mnt
```


## 3. 基本的なシステムの設定

`hostnamectl`や`localectl`といった`systemd`サービスは、どうやら一時的にしか設定を変更してくれないようです。永続的に変更したい場合は、ファイルを作成して直接編集するのが良いと思われます。

対話的に設定したい場合は、`systemd-firstboot`を利用すれば可能なようです。


### タイムゾーン(`/etc/localtime`)

```bash
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

シンボリックリンクを張った後、`hwclock`でハードウェアクロックをUTC時刻系に設定しました。

```bash
hwclock --systohc --utc
```


### ロケール('/etc/locale.conf`)
`/etc/locale.gen`を編集して使用するロケールをアンコメントして、`locale-gen`を実行しました。ここでは、`en_US.UTF-8 UTF-8`と`ja_JP.UTF-8 UTF-8`をアンコメントしました。

```bash
locale-gen
```

`localectl list-locales`を使用すると、ロケールが生成されていることが確認できます。
確認した後は、次のコマンドを実行して、`/etc/locale.conf`を作成しました。


`ja_JP.utf8`に設定したいところですが、以前インストールしたときにいくつかの文字が豆腐になっていたので、今回は`en_US.utf8`に設定しました。


```bash
echo LANG=en_US.utf8 > /etc/locale.conf
```

### コンソールキーマップ(`/etc/vconsole.conf`)

```bash
echo KEYMAP=jp106 > /etc/vconsole.conf
```


### ホストネーム(`/etc/hostname`)

```bash
echo arch-vmware > /etc/hostname
```


`/etc/hosts`に、以下の通りに記述しました。

```:/etc/hosts
127.0.0.1   localhost
::1 localhost
127.0.1.1   arch-vmware.localdomain arch-vmware
```


## 4. ネットワーク設定

今回使うネットワークのサービスは

- `systemd-networkd.service`
- `systemd-resolved.service` 

です。


まず二つのサービスを有効化しました。

```bash
systemctl enable systemd-networkd systemd-resolved
```

また、`/etc/nsswitch.conf`を開き、`hosts:`行において、`resolve`が`dns`よりも左にあることを確認しました。

設定の確認は、インストールディスクで起動しているこの段階ではできません。インストール後の最初の起動のあとに確認します。



### ネットワーク

今回は`/etc/systemd/network/50-main.network`を作成し、以下のとおりに記入しました。

```toml:/etc/systemd/network/50-main.network
[Match]
Name=ens33
Virtualization=yes

[Network]
DHCP=yes
```

`Name`行には`ip a`で出てきたインターフェース名を記入しました。



### ネームサーバ

`systemd-resolved.service`は下記の順にネームサーバを参照します。

1. /etc/systemd/resolved.conf
2. /etc/systemd/resolved.conf.d/*.conf
3. /run/systemd/resolved.conf.d/*.conf
4. /usr/lib/systemd/resolved.conf.d/*.conf

今回は、`/etc/systemd/resolved.conf`を編集しました。
`[Resolve]`セクションの`DNS`行をアンコメントし、使いたいネームサーバのIPアドレスを追記しました。

```toml:/etc/systemd/resolved.conf
[Resolve]
DNS=8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
```

ちなみに、`/etc/resolv.conf`も参照するようですが、動的に作られた`/run/systemd/resolve/resolv.conf`を見るに、優先順位は低いようです。

シンボリックリンクにしてしまえば参照しないようです。

この段階では、サービスが起動していない、つまり、`/run/systemd/resolve/resolv.conf`が作られていないので、`/etc/resolv.conf`をシンボリックリンクに置き換える作業は、あとに回しました。


## 5. Initramfs(イニシャルRAMディスク)の生成

`pacstrap`を実行した時点で、`/boot`に作成されていました。


## 6. ブートローダの設定
ブートローダは`systemd-boot`を使用することにしました。

```bash
# インストール
bootctl --path=/boot install
```

ローダーを追加します。

まず、`/boot/loader/loader.conf`を編集して、使用するエントリを指定しました。
エントリとは、`/boot/loader/entries/`内のファイルのことです。

```:/boot/loader/loader.conf
# defaultオプションにデフォルトで選択するエントリを拡張子を外した状態で指定します。
# デフォルトなのにワイルドカード*が使えるところが理解しにくい。どゆこと？
default arch-*
timeout 3
console-mode auto
```


次に`/boot/loader/entries/arch-main.conf`を作成しました。内容は、以下のとおりです。

```:/esp/loader/entries/arch-main.conf
title   Arch Linux
linux   /vmlinuz-linux
initrd  /amd-ucode.img
initrd  /initramfs-linux.img
options root=UUID=(UUID)
options rootfstype=ext4
options rw
```
`root`オプションで指定されているUUIDは、`blkid`コマンドで確認しました。

マイクロコードのアップデートを有効にするために、`initramfs`よりも前に`initrd`で追加しました。


# 再起動

`chroot`環境は`exit`で抜けることができます。

再起動後、rootアカウントでログインしました。



## /etc/resolv.confのシンボリックリンク化

`sistemd-resolved.service`を使用しているので、`resolve.conf`をシンボリックリンクに書き換えました。

```bash
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
```



## rootユーザのパスワードの設定

ネットワークの設定を確認した後、rootアカウントのパスワードを設定しました。

```bash
passwd
```


## 新規ユーザの追加

新規ユーザowlを追加しました。

```bash
useradd -m owl
passwd owl
```

## sudoの設定

先ほど作成したユーザに、`sudo`実行時に`root`権限を与えられるようにしました。

`visudo`を実行後、以下のエントリを追加しました。

```:visudo
owl ALL=(ALL) ALL
```


これで、ArchLinuxのインストールは終了です。

後日、GUIの設定をしてみるつもりです。


# 感想

バインドマウントって意味あるの？　普通に書き込めるのだけど。