Thinkpad X1 Carbon (Gen 4)にArch Linuxをインストールする

Thinkpad X1 Carbonを入手しました。2016年に発売された第4世代のものです。
これに[Arch Linux](https://www.archlinux.org/)をインストールしようと思います。

## 方針

- Arch Linuxを導入する
  - Linux単体で使う
  - 入手時にWindows 10が導入されていたが、消す
- SSD
  - dm-crypt、LUKSで暗号化して、LVMで管理する
  - ファイルシステムはext4を使う
  - スワップは作らない

ちなみにこのPC、NVMe SSDが使われていました。NVMeを扱うのが自分はこれがはじめてだったのですが、特に困ったことはありませんでした。今まで通りの手順でインストールできています。

## インストール前の準備

### インストールメディアをつくる

- [USB インストールメディア - ArchWiki](https://wiki.archlinuxjp.org/index.php/USB_%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2)

### インストールメディアからLinuxを起動する

0. USBメモリをさし、電源ON
0. LENOVOロゴの画面で`Enter`を押す
0. Startup Interrupt Menuの画面で`F1`を押す
0. Secure Bootを無効にする
  0. Security＞Secure Boot
  0. Secure BootがDisabledであることを確認
0. USBメモリのLinuxの起動を最優先にする
  0. `ESC`を押して、Startup＞Boot
  0. USBメモリのBoot Priority Orderを1番にする
0. `F10` (Save and Exit)を押して、Yesを選択する
0. 再起動し、インストールメディアが起動する

### リモート接続を受け付ける

まずsshサーバを起動し、リモートからログインして作業できるようにする。

```shell-session
root@archiso ~ # loadkeys jp106
root@archiso ~ # wifi-menu
root@archiso ~ # ping -4 -c 3 ftp.tsukuba.wide.ad.jp
root@archiso ~ # ping -4 -c 3 ftp.jaist.ac.jp
root@archiso ~ # passwd
root@archiso ~ # systemctl start sshd
root@archiso ~ # ip addr
```

[X1 Carbon 2016(Gen 4)にArch Linuxをインストール - pockestrap](http://pocke.hatenablog.com/entry/2016/06/18/180914)を読んで、真似してみた。コピペがし易く、ログを残すのが簡単になるので、大変よかった。

## 手順

SSHログインした直後から。

### キーボードは日本語を使う

```shell-session
root@archiso ~ # loadkeys jp106
```

### 時刻合わせ

```shell-session
root@archiso ~ # timedatectl set-ntp true
```

### パーティションテーブルを作成する

EFIパーティションと暗号化するパーティションの2件を作成する。
スワップパーティションを作らないのは前提に書いたとおり。

```shell-session
root@archiso ~ # parted /dev/nvme0n1 \
>   -s mklabel gpt \
>   -s mkpart ESP fat32 1MiB 513MiB \
>   -s set 1 boot on \
>   -s mkpart primary ext4 513MiB 100%
root@archiso ~ # parted /dev/nvme0n1 print
Model: Unknown (unknown)
Disk /dev/nvme0n1: 512GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End    Size   File system  Name  Flags
 1      1049kB  538MB  537MB  fat32              boot, esp
 2      538MB   512GB  512GB
```

### EFIパーティションを作成する

```shell-session
root@archiso ~ # mkfs.vfat -F32 /dev/nvme0n1p1
mkfs.fat 4.1 (2017-01-24)
```

### LUKSコンテナを作成する

```shell-session
root@archiso ~ # cryptsetup luksFormat /dev/nvme0n1p2

WARNING!
========
This will overwrite data on /dev/nvme0n1p2 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: <パスワード>
Verify passphrase: <再度、パスワード>
```

### LUKSコンテナにLVMボリュームを作成する

- 物理ボリューム: /dev/mapper/lvm
  - ボリュームグループ: volume
    - 論理ボリューム #1: root
      - 20GB
      - `/`にマウントする
    - 論理ボリューム #2: home
      - 残り全部
      - `/home`にマウントする

```shell-session
root@archiso ~ # cryptsetup open /dev/nvme0n1p2 lvm
Enter passphrase for /dev/nvme0n1p2:
root@archiso ~ # pvcreate /dev/mapper/lvm
  Physical volume "/dev/mapper/lvm" successfully created.
root@archiso ~ # vgcreate volume /dev/mapper/lvm
  Volume group "volume" successfully created
root@archiso ~ # lvcreate --size 20G volume --name root
  Logical volume "root" created.
root@archiso ~ # lvcreate --extents +100%FREE volume --name home
  Logical volume "home" created.
```

### ファイルシステムを作成する

```shell-session
root@archiso ~ # mkfs.ext4 /dev/mapper/volume-root
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: 335c2dd4-154c-4a0b-9440-706ed5ce55f2
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

root@archiso ~ # mkfs.ext4 /dev/mapper/volume-home
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 119651328 4k blocks and 29917184 inodes
Filesystem UUID: 2187ac2c-c677-44b0-808e-256bf03857ce
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done
```

### ファイルシステムをマウントする

```shell-session
root@archiso ~ # mount /dev/mapper/volume-root /mnt
root@archiso ~ # mkdir /mnt/home
root@archiso ~ # mount /dev/mapper/volume-home /mnt/home
root@archiso ~ # mkdir /mnt/boot
root@archiso ~ # mount /dev/nvme0n1p1 /mnt/boot
```

### パッケージインストールのミラーを設定する

```
root@archiso ~ # cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
root@archiso ~ # grep -A 1 --no-group-separator '^## Japan' /etc/pacman.d/mirrorlist.backup | grep -v '^## Japan' > /etc/pacman.d/mirrorlist
```

### ベースシステムをインストールする

```shell-session
root@archiso ~ # pacstrap /mnt base base-devel
(略)
```

### fstabファイルを作成する

```shell-session
root@archiso ~ # genfstab -U /mnt >> /mnt/etc/fstab
```

### 新しいシステムにchrootする

```shell-session
root@archiso ~ # arch-chroot /mnt
```

### ホスト名を設定する

```shell-session
[root@archiso /]# NEW_HOSTNAME=susi
[root@archiso /]# echo "$NEW_HOSTNAME" > /etc/hostname
[root@archiso /]# echo "127.0.1.1      ${NEW_HOSTNAME}.localdomain  $NEW_HOSTNAME" >> /etc/hosts
```

### タイムゾーンを設定する

```shell-session
[root@archiso /]# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
[root@archiso /]# hwclock --systohc
```

### ロケールを設定する

```shell-session
[root@archiso /]# sed -i 's/^#en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
[root@archiso /]# sed -i 's/^#ja_JP.UTF-8/ja_JP.UTF-8/' /etc/locale.gen
[root@archiso /]# locale-gen
Generating locales...
  en_US.UTF-8... done
  ja_JP.UTF-8... done
Generation complete.
[root@archiso /]# cat << __LOCALE_CONF__ > /etc/locale.conf
> LANG=en_US.UTF-8
> LC_ALL=
> __LOCALE_CONF__
[root@archiso /]# echo 'KEYMAP=jp106' > /etc/vconsole.conf
```

### rootのパスワードを設定する

```shell-session
[root@archiso /]# passwd
New password:
Retype new password:
passwd: password updated successfully
```

### initramfsを作成する

```shell-session
[root@archiso /]# sed -i.backup '/^HOOKS=/ s/ filesystems / encrypt lvm2 resume filesystems /' /etc/mkinitcpio.conf
[root@archiso /]# mkinitcpio --preset linux
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'default'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
==> Starting build: 4.11.9-1-ARCH
  -> Running build hook: [base]
  -> Running build hook: [udev]
  -> Running build hook: [autodetect]
  -> Running build hook: [modconf]
  -> Running build hook: [block]
  -> Running build hook: [encrypt]
  -> Running build hook: [lvm2]
  -> Running build hook: [resume]
  -> Running build hook: [filesystems]
  -> Running build hook: [keyboard]
  -> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: /boot/initramfs-linux.img
==> Image generation successful
==> Building image from preset: /etc/mkinitcpio.d/linux.preset: 'fallback'
  -> -k /boot/vmlinuz-linux -c /etc/mkinitcpio.conf -g /boot/initramfs-linux-fallback.img -S autodetect
==> Starting build: 4.11.9-1-ARCH
  -> Running build hook: [base]
  -> Running build hook: [udev]
  -> Running build hook: [modconf]
  -> Running build hook: [block]
==> WARNING: Possibly missing firmware for module: aic94xx
==> WARNING: Possibly missing firmware for module: wd719x
  -> Running build hook: [encrypt]
  -> Running build hook: [lvm2]
  -> Running build hook: [resume]
  -> Running build hook: [filesystems]
  -> Running build hook: [keyboard]
  -> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: /boot/initramfs-linux-fallback.img
==> Image generation successful
```

aic94xx、wd719xのファームウェアがない、とWARNINGがでているけど……
そのファームウェアは必要なんだろうか？

### ブートローダーをインストールする

systemd-bootを使う。

```shell-session
[root@archiso /]# bootctl --path=/boot install
Created "/boot/EFI".
Created "/boot/EFI/systemd".
Created "/boot/EFI/BOOT".
Created "/boot/loader".
Created "/boot/loader/entries".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/systemd/systemd-bootx64.efi".
Copied "/usr/lib/systemd/boot/efi/systemd-bootx64.efi" to "/boot/EFI/BOOT/BOOTX64.EFI".
Created EFI boot entry "Linux Boot Manager".
[root@archiso /]# echo 'default arch' >> /boot/loader/loader.conf
[root@archiso /]# echo 'timeout 5' >> /boot/loader/loader.conf
[root@archiso /]# UUID_CRYPTDEVICE=$(find /dev/disk/by-uuid -lname ../../nvme0n1p2 -printf "%f\n" | head -n 1)
[root@archiso /]# cat << __ARCH_CONF__ > /boot/loader/entries/arch.conf
> title Arch Linux
> linux /vmlinuz-linux
> initrd /initramfs-linux.img
> options cryptdevice=UUID=${UUID_CRYPTDEVICE}:volume root=/dev/mapper/volume-root rw intel_pstate=no_hwp
> __ARCH_CONF__
```

### 再起動する

```shell-session
[root@archiso /]# exit
exit
arch-chroot /mnt  11.15s user 1.54s system 4% cpu 4:17.33 total
root@archiso ~ # umount -R /mnt
root@archiso ~ # reboot
```