概要
最近、Arch Linuxを触り始めました。CentOSやUbuntuといったインストーラが提供されているLinuxは扱ったことがあるのですが、Arch LinuxはCLIからコマンドを打ち込んでインストール作業を進める感じなので、だいぶ硬派な感じです。
Arch LinuxはCLIから作業することもあり、インストール手順を間違えた際に手順を一からやり直すのがちょっと面倒なので、「インストールをミスっちゃた…🥺」というガッカリ感があります。何回かインストールを繰り返すことで手順を憶えてゆくという考え方もありますが、できればインストールのトライ&エラーのサイクルは小さくしたいものです。
(短い期間で手順を憶えられるなら、それに越したことはないですよね)
何か良い方法はないだろうか…と考えてみたら、Linuxのループバックデバイスを利用することで、Arch Linuxのインストール練習を効率的に行えそうな気がしてきました。調べてみたところ、思いのほか上手いことインストール練習用環境が構築できたので、一連の手順をメモしておこうと思います。
ループバックデバイスを利用したArch Linuxインストール
Linuxにはループバックデバイスというものがあり、 /dev/loop0
のようなデバイスとファイルを紐づけることができます。よくある例としてはISOイメージをmountするようなケースがあるかと思います。
$ sudo mkdir /cdrom
$ sudo mount -o loop archlinux-2021.05.01-x86_64.iso /cdrom
ディスクに見立てたファイルを /dev/loop0
として扱うことでArch Linuxの一連のインストール手順の練習環境にできそうです。
今回の環境
今回試した環境は、Arch Linuxの上でディスクに見立てたファイルにArch Linuxをインストールし、QEMUで動かす(動作確認する)という形になっています。
そのため、あらかじめ「Arch Linuxがインストールされた環境が用意されていること」という鶏卵問題が存在しています…。
事前準備
CDブートしてArch Linuxをインストールする場合は必要なコマンドが揃っていますが、インストール後のArch Linux環境ではそれらのコマンドが用意されていません。そのため、あらかじめArch Linuxのインストールに必要なパッケージを用意します。
$ # Arch Linuxのインストールに必要なパッケージを用意する。
$ sudo pacman -S \
extra/qemu \
extra/edk2-ovmf \
extra/gptfdisk \
extra/gparted \
arch-install-scripts \
dosfstools
ディスクに見立てたファイルを用意する
4GBほどのファイルを用意し、 /dev/loop0
に紐づけます。
$ # 4GBのディスクに見立てたファイルを作成する。
$ touch disk.img
$ dd if=/dev/zero of=disk.img bs=1M count=$((1024*4))
$
$ # loop0(ループバックデバイス)にファイルを設定する。
$ sudo losetup /dev/loop0 disk.img
$ losetup -l
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 0 /home/arch/work/disk.img 0 512
パーティションを設定する
/dev/loop0
に対してArch Linuxインストール用のパーティションを設定します。
今回はLinuxインストール用のパーティションを設定していますが、様々なファイルシステム向けのパーティションを設定するといった実験にも応用できそうです。
$ # パーティションを設定する。
$ sudo gdisk /dev/loop0
gdiskコマンドを使用してパーティションを設定します。
EFIシステムパーティションの作成
Command (? for help): n ★入力
Partition number (1-128, default 1):
First sector (34-8388574, default = 2048) or {+-}size{KMGTP}:
Last sector (2048-8388574, default = 8388574) or {+-}size{KMGTP}: 512M ★入力
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef00 ★入力
Changed type of partition to 'EFI system partition'
スワップパーティションの作成
スワップパーティションのサイズは512MBとします。
Command (? for help): n ★入力
Partition number (2-128, default 2):
First sector (34-8388574, default = 1050624) or {+-}size{KMGTP}:
Last sector (1050624-8388574, default = 8388574) or {+-}size{KMGTP}: 1024M ★入力
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 8200 ★入力
Changed type of partition to 'Linux swap'
Linuxパーティションの作成
最後にLinuxパーティションを作成します。ここはほぼEnterでデフォルト値のまま入力するだけでOKです。
Command (? for help): n ★入力
Partition number (3-128, default 3):
First sector (34-8388574, default = 2099200) or {+-}size{KMGTP}:
Last sector (2099200-8388574, default = 8388574) or {+-}size{KMGTP}:
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
パーティション情報の書き込み
作成されたパーティションは以下になります。
Command (? for help): p ★入力
Disk /dev/loop0: 8388608 sectors, 4.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 81F92DF9-A075-4CAC-9D0F-556F5DBD6BF6
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 8388574
Partitions will be aligned on 2048-sector boundaries
Total free space is 6108 sectors (3.0 MiB)
Number Start (sector) End (sector) Size Code Name
1 2048 1048576 511.0 MiB EF00 EFI system partition
2 1050624 2097152 511.0 MiB 8200 Linux swap
3 2099200 8388574 3.0 GiB 8300 Linux filesystem
最後にパーティション情報を書き込んで作業完了です。
Command (? for help): w ★入力
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/loop0.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
$
gdiskを終了した後は、パーティション情報を再読み込みすることで、作成したパーティション( /dev/loop0p1
とか)が見えるようになります。
$ # パーティション情報を再読み込みする。
$ sudo partprobe /dev/loop0
ファイルシステムのフォーマットとマウント
作成したパーティション上にファイルシステムを作成します。
$ # EFIパーティションをフォーマットする。
$ sudo mkfs.fat -F32 /dev/loop0p1
$
$ # スワップを作成する。
$ sudo mkswap /dev/loop0p2
$
$ # Linuxパーティションをフォーマットする。
$ sudo mkfs.ext4 /dev/loop0p3
Arch Linuxではファイルシステムに対してCLI上からインストールを進めるため、EFTとLinuxのパーティションをマウントします。
$ # /mnt/bootにはEFTパーティションをマウントするため、
$ # Linuxパーティション→EFIパーティションの順でマウントする。
$ sudo mount /dev/loop0p3 /mnt
$ sudo mkdir /mnt/boot
$ sudo mount /dev/loop0p1 /mnt/boot
Arch Linuxの配布物をインストールする
配布物のインストールは pacstrap
コマンドで行います。
$ # Arch Linuxの配布物をインストールする。
$ sudo pacstrap /mnt base linux linux-firmware
/etc/fstabの設定
genfstab
コマンドで /etc/fstab
を生成します。
$ genfstab -U /mnt | sudo tee -a /mnt/etc/fstab
# /dev/loop0p3
UUID=a322f882-4104-4677-93de-4eabdd284da3 / ext4 rw,relatime 0 1
# /dev/loop0p1
UUID=5631-C2B0 /boot vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=ascii,shortname=mixed,utf8,errors=remount-ro 0 2
# /dev/sda2
UUID=ca6f5a48-18db-433f-9c65-347325718f5f none swap defaults 0 0
ブートローダの設定
ブートローダーの設定を行います。ここからは arch-chroot
で /dev/loop0
が指すパーティションにchrootして作業します。
$ sudo arch-chroot /mnt
[root@arch /]# # 設定ファイルの編集用にviをインストールします。
[root@arch /]# pacman -S vi
EFIパーティションにbootctlをインストールします。
[root@arch /]# bootctl install
ブート時に使用するデフォルトコンフィグを作成します。ここでは arch
というデフォルトコンフィグを参照する設定としています。
[root@arch /]# vi /boot/loader/loader.conf
...(loader.confの内容を編集する)...
[root@arch /]# cat /boot/loader/loader.conf
default arch
timeout 3
#console-mode keep
editor no
デフォルトコンフィグは /boot/loader/entries/arch.conf
に作成します。
# cat <<_EOF > /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
_EOF
#
# # ルートパーティションのUUIDを使用する設定があるので、
# # これは/etc/fstabから抽出する。
# cat /etc/fstab | grep ext4 | awk '{ print "options root="$1" rw" }' >> /boot/loader/entries/arch.conf
今回の例では、以下のような設定内容になります。
# bootctl list
Boot Loader Entries:
title: Arch Linux (default)
id: arch.conf
source: /boot/loader/entries/arch.conf
linux: /vmlinuz-linux
initrd: /initramfs-linux.img
options: root=UUID=a322f882-4104-4677-93de-4eabdd284da3 rw
title: Reboot Into Firmware Interface
id: auto-reboot-to-firmware-setup
source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
Rootパスワードの設定
Rootパスワードの設定を行います。
# passwd
これで一連の設定は完了です。 exit
コマンドでchroot環境から抜けます。
# exit
$
マウントを解除する
最後に各ファイルシステムのマウントを解除します。
$ sudo umount /mnt/boot
$ sudo umount /mnt
$ mount | grep /mnt | wc -l
0
インストールしたArch Linuxを起動する
$ sudo qemu-system-x86_64 \
-bios /usr/share/edk2-ovmf/x64/OVMF.fd \
-m 512M \
-boot order=c \
-hdd /dev/loop0
上手く起動できなかった場合
ここまで全てが上手くいっていた場合はArch Linuxが起動してきますが、何か問題が発生して起動に失敗することもあり、その場合に再度Arch Linuxのインストールをやり直すのは大変です。
ここでループバックデバイスを利用してインストールしていると、ファイルシステムをマウントしなおしてトラブルシューティングと修正作業が容易に行えます。起動に失敗したQEMUを停止した後、以下のコマンドでファイルシステムを再マウントします。
$ sudo mount /dev/loop0p3 /mnt
$ sudo mount /dev/loop0p1 /mnt/boot
$ sudo arch-chroot /mnt
#
良くありがちなミスが、 /boot/loader/entries/arch.conf
の options
の記述を間違えている、というものです。
(個人的には、起動できなかった場合の原因は options
の設定が間違っていることがほとんどでした...)
$ grep options /boot/loader/entries/arch.conf
options root=UUID=20174e0a-be82-4683-b404-5236d8c3e8de rw
間違っている個所を修正したら、chroot環境を抜けたあとにファイルシステムをアンマウントします。
マウントしたままだとQEMUから /dev/loop0
を参照した際にファイルシステムの変更内容が反映されていないことがあるため、面倒でも都度アンマウントするのが良いかもしれません。
# exit
$ sudo umount /mnt/boot
$ sudo umount /mnt
$ mount | grep /mnt | wc -l
まとめ
ループバックデバイスと組み合わせた、Arch Linuxのインストール手順とトラブルが出た際の調査・修正方法を紹介しました。
ファイルシステムを参照して原因調査を行えるという点では、インストール手順を振り返りながら修正できるため、Arch Linuxの硬派なインストール手順という利点(?)をより活かせそうです。