概要
先日#GentooInstallBattleに初挑戦して無事に勝利することができました。#GentooInstallBattleは何かというと、LinuxディストリビューションであるGentoo Linuxを、無事にインストールできるかどうかの挑戦のことで、Twitter上でハッシュタグとしてよく使用されています。
以下のリンクはその時のYoutubeの配信動画です。6時間近くもかかってしまいました…。
#GentooInstallBattle Round 1 – VirtualBox –
Gentoo LinuxはPortageというパッケージ管理ツールを使用して、ソースから様々なソフトウェアをビルドして構築します。自分で本当に必要なパッケージを取捨選択していくため、使いこなすためには様々なパッケージへの理解が必須で、大変奥が深いディストリビューションだと思います。
基本公式のハンドブックを参照すれば、無事にインストールすることはできると思います。これのおかげで勝利することができました。
しかし、結局何が行われたのか、理解がとても浅かったので、初戦の選択肢を振り返りながら、概念を整理しまとめていきたいと思います。
環境
- ホストOS(macOS Catalina 10.15.7)
- VirtualBox 6.1.16
#GentooInstallBattle
MinimalインストールCDの入手
今回はCPUの64bitアーキテクチャであるAMD64用のMinimalインストールCDを採用します。
Gentoo source mirrorsのここから、install-amd64-minimalという名前のISOイメージを入手します。
仮想マシンの用意
VirutalBoxマネージャを開き、仮想マシンを作成します。インストール検証用のため、特にこだわらずに以下のスペックで作成します。
- 仮想マシン名: Gentoo
- メモリサイズ: 4096MB
- 仮想ハードディスク: VDI & 可変サイズ & 20GB
- ネットワークアダプタ: ブリッジアダプタ
仮想マシンの起動 & 設定
起動するとboot: というプロンプトが表示されますが、何も入力せずにEnterを押します。そうすると、デフォルトのカーネル(K8 CPUとEM64T対応)が選択されたことになります。
仮想マシンのネットワーク設定にはネットワークアダプタを採用したので、ゲストOSとホストOS間、ゲストOSとネットワーク間で通信ができるようになっています。ip aコマンドでインターフェース名とアドレスを確認します。
# ip a
------(省略)------
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:0d:2c:17 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.3/24 brd 192.168.0.255 scope global dynamic noprefixroute enp0s3
valid_lft 3377sec preferred_lft 2927sec
------(省略)-------
確認したら、ホストOSからrootユーザでssh接続したいので、そのためにまずはrootユーザのパスワードを設定します。その後、sshdを起動します。
# passwd
# rc-service sshd start
ではホストOSからssh接続をします。
% ssh root@192.168.0.3
以下のコマンドで外部のネットワークと通信できることを確認します。
# ping -4 -c 3 www.gentoo.org
パーティション作成
仮想ハードディスクが/dev/sdaとして認識されていると思います。今回はUEFIモードでの起動を採用しますが、ハンドブックと同様に、BIOSモードでの起動に対応できるよう、BIOSブートパーティションも作成しています。
パーティション | ファイルシステム | サイズ | 説明 |
/dev/sda1 | (ブートローダ) | 2M | BIOSブートパーティション |
/dev/sda2 | fat32 | 128M | ブートパーティション |
/dev/sda3 | (swap) | 512M | スワップパーティション |
/dev/sda4 | ext4 | 残り全部 | ルートパーティション |
UEFIでの起動を選択したので、パーティションの規格はGPTを選択します。ではpartedコマンドでパーティションを作成していきます。-aオプションでoptimalを指定することで、パーティションのアライメント(並び、整列)を最適にしてくれます。アライメントが合っていない場合だと、データのアクセス速度に違いが出るようです。
参考: 2TB HDDのアライメントについて… 本当に速くなるの?
# parted -a optimal /dev/sda
GNU Parted 3.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print #何も設定されていないことを確認
Error: /dev/sda: unrecognised disk label
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:
(parted) mklabel gpt #パーティションテーブルの形式をGPTに設定
(parted) unit mib #サイズ単位をMB単位に変更
(parted) mkpart primary 1 3 #1~3MBまでのパーティションを作成
(parted) name 1 grub #1番目のパーティションにgrubと名付ける
(parted) set 1 bios_grub on #1番目のパーティションにbios_grubフラグを設定
(parted) mkpart primary 3 131 #3~131MBまでのパーティションを作成
(parted) name 2 boot #2番目のパーティションにbootと名付ける
(parted) mkpart primary 131 643 #131~643MBまでのパーティションを作成
(parted) name 3 swap #3番目のパーティションにswapと名付ける
(parted) mkpart primary 643 -1 #643~ディスクの限界までのパーティションを作成
(parted) name 4 rootfs #4番目のパーティションにrootfsと名付ける
(parted) set 2 boot on #2番目のパーティションにbootフラグを設定(UEFIの場合必須)
(parted) print #パーティションテーブルを確認
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 20480MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1.00MiB 3.00MiB 2.00MiB grub bios_grub
2 3.00MiB 131MiB 128MiB boot boot, esp
3 131MiB 643MiB 512MiB swap
4 643MiB 20479MiB 19836MiB rootfs
(parted) quit
Information: You may need to update /etc/fstab.
ファイルシステム作成
partedコマンドのprintで表示されているとおり、まだファイルシステムを作成していないので、ブートパーティションの/dev/sda2とルートパーティションの/dev/sda4に作成します。
# mkfs.fat -F 32 /dev/sda2
mkfs.fat 4.1 (2017-01-24)
# mkfs.ext4 /dev/sda4
mke2fs 1.45.5 (07-Jan-2020)
Creating filesystem with 5078016 4k blocks and 1269760 inodes
Filesystem UUID: a80d75f2-c8aa-46cf-9d34-06ff0ccde7b3
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
スワップの有効化
スワップ専用のパーティションとして作成するために、mkswapコマンドで初期化し、swaponコマンドで有効化します。
# mkswap /dev/sda3
Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=3122f9a9-85ef-4487-85fe-336ed57cb0f3
# swapon /dev/sda3
ルートパーティションのマウント
/mnt/gentooディレクトリに、ルートパーティションである/dev/sda4をマウントします。
# mount /dev/sda4 /mnt/gentoo
stage3のダウンロード
stage3は、最小限のgentoo環境がアーカイブとしてまとめられているもので、これをルートパーティションである/dev/sda4内にダウンロードして展開していきます。
先程/dev/sda4を/mnt/gentooにマウントしたので、ここに移動してダウンロード&展開します。
# cd /mnt/gentoo
MinimalインストールCDをインストールした場所(ここ)から、AMD64用のstage3 tarballのアドレスを取得してwgetでダウンロードし、tarコマンドで展開します。
# wget --inet4-only http://ftp.iij.ad.jp/pub/linux/gentoo/releases/amd64/autobuilds/current-install-amd64-minimal/stage3-amd64-20201202T214503Z.tar.xz
# tar xpvf stage3-amd64-20201202T214503Z.tar.xz --xattrs-include='*.*' --numeric-owner
コンパイルオプションの設定
# vi /mnt/gentoo/etc/portage/make.conf
#-march=native追記(ターゲットアーキテクチャに現在のシステムのアーキテクチャを指定)
COMMON_FLAGS="-march=native -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
MAKEOPTS="-j2" #追記
------(省略)-------
:wq!
ミラーサイトの選択
Japan: Internet Initiative Japanにある三つのミラーサイトを登録します。こうすることで、ソースコードのダウンロード時間を短縮することができます。
# mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf
ebuildリポジトリの設定
ebuildリポジトリとは、パッケージのメタデータ(概要、ライセンス、依存関係等)と構築手順が書かれているebuildファイルの集合体のことです。パッケージ管理ツールであるPortageは、このリポジトリ内の対象のebuildを参照することで、パッケージのダウンロードとインストールを行います。
以下のコマンドでリポジトリの設定ファイルを置くためのディレクトリを作成します。
# mkdir --parents /mnt/gentoo/etc/portage/repos.conf
このディレクトリ内にリポジトリ設定ファイルの雛形をコピーして配置します。
# cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
catコマンドで設定ファイルの内容を確認すると以下のように表示されます。
# cat /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
[DEFAULT]
main-repo = gentoo
[gentoo]
location = /var/db/repos/gentoo
sync-type = rsync
sync-uri = rsync://rsync.gentoo.org/gentoo-portage
auto-sync = yes
sync-rsync-verify-jobs = 1
sync-rsync-verify-metamanifest = yes
sync-rsync-verify-max-age = 24
sync-openpgp-key-path = /usr/share/openpgp-keys/gentoo-release.asc
sync-openpgp-keyserver = hkps://keys.gentoo.org
sync-openpgp-key-refresh-retry-count = 40
sync-openpgp-key-refresh-retry-overall-timeout = 1200
sync-openpgp-key-refresh-retry-delay-exp-base = 2
sync-openpgp-key-refresh-retry-delay-max = 60
sync-openpgp-key-refresh-retry-delay-mult = 4
sync-webrsync-verify-signature = yes
DNS情報のコピー
新しく作った環境でもネットワークを使用できるように、以下のコマンドでネームサーバの情報が書かれている/etc/resolv.confをコピーしてきます。
# cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
ファイルシステムのマウント
これからchrootしても、現在作成中の新しい環境で作業できるように、必要なディレクトリをマウントしておきます。
# mount --types proc /proc /mnt/gentoo/proc
# mount --rbind /sys /mnt/gentoo/sys
# mount --make-rslave /mnt/gentoo/sys
# mount --rbind /dev /mnt/gentoo/dev
# mount --make-rslave /mnt/gentoo/dev
chroot
chrootを行ったことで、/mnt/gentooが/ とみなされ、exitで出ない限り、外のディレクトリには移動できなくなります。
# chroot /mnt/gentoo /bin/bash
/etc/profileというログインしたときに読み込まれる、環境変数等が書かれたファイルをリロードします。
# source /etc/profile
chroot環境であることがわかりやすいように、PS1というプロンプトの表示を設定する環境変数を変更します。
# export PS1="(chroot) ${PS1}"
ブートパーティションのマウント
この後のカーネルのコンパイルやブートローダのインストールで/bootディレクトリが必須になるので、ブートパーティションである/dev/sda2をマウントしておきます。
# mount /dev/sda2 /boot
ebuildリポジトリの更新
以下のコマンドで最新のebuildリポジトリのスナップショットを取得してきます。
# emerge-webrsync
プロファイル設定
プロファイルはGentooのシステムの基礎部分となるもので、インストールするパッケージの範囲やバージョンを決めているものです。
このように様々なセットがありますが、今回はstable版のsystemdを選択します。
# eselect profile list
Available profile symlink targets:
[1] default/linux/amd64/17.1 (stable) *
[2] default/linux/amd64/17.1/selinux (stable)
[3] default/linux/amd64/17.1/hardened (stable)
[4] default/linux/amd64/17.1/hardened/selinux (stable)
[5] default/linux/amd64/17.1/desktop (stable)
[6] default/linux/amd64/17.1/desktop/gnome (stable)
[7] default/linux/amd64/17.1/desktop/gnome/systemd (stable)
[8] default/linux/amd64/17.1/desktop/plasma (stable)
[9] default/linux/amd64/17.1/desktop/plasma/systemd (stable)
[10] default/linux/amd64/17.1/developer (stable)
[11] default/linux/amd64/17.1/no-multilib (stable)
[12] default/linux/amd64/17.1/no-multilib/hardened (stable)
[13] default/linux/amd64/17.1/no-multilib/hardened/selinux (stable)
[14] default/linux/amd64/17.1/systemd (stable)
今は*印がついている1番目が選択されているので、14番目に以下のコマンドで変更して、*印が変わったことを確認します。
# eselect profile set 14
# eselect profile list
[1] default/linux/amd64/17.1 (stable)
[2] default/linux/amd64/17.1/selinux (stable)
[3] default/linux/amd64/17.1/hardened (stable)
[4] default/linux/amd64/17.1/hardened/selinux (stable)
[5] default/linux/amd64/17.1/desktop (stable)
[6] default/linux/amd64/17.1/desktop/gnome (stable)
[7] default/linux/amd64/17.1/desktop/gnome/systemd (stable)
[8] default/linux/amd64/17.1/desktop/plasma (stable)
[9] default/linux/amd64/17.1/desktop/plasma/systemd (stable)
[10] default/linux/amd64/17.1/developer (stable)
[11] default/linux/amd64/17.1/no-multilib (stable)
[12] default/linux/amd64/17.1/no-multilib/hardened (stable)
[13] default/linux/amd64/17.1/no-multilib/hardened/selinux (stable)
[14] default/linux/amd64/17.1/systemd (stable) *
@worldの更新
以下のコマンドで、gentooベースシステムを構築する様々なパッケージ群を更新します。
# emerge --ask --verbose --update --deep --newuse @world

とてもきれいですね。。自分の環境ではここの処理が一番時間がかかりました。一時間は余裕で越えていたと思います。
タイムゾーンの設定
/usr/share/zoneinfoを確認し、タイムゾーンを日本に設定します。
# echo "Japan" > /etc/timezone
以下のコマンドを実行することで、システムのライブラリがタイムゾーンを知るために参照する/etc/localtimeを、/etc/timezoneを元にアップデートします。
# emerge --config sys-libs/timezone-data
Vimのインストール
このままだとnanoしかない、、のでemergeコマンドでvimをインストールします。
# emerge --ask app-editors/vim
ロケールの設定
英語勉強中なので日本語は入れません。デフォルトで入っているC.UTF-8に加えて、en_US.UTF-8を設定ファイルに追加します。
# vi /etc/locale.gen
en_US.UTF-8 UTF-8
C.UTF8 UTF-8
locale-genコマンドで/etc/locale.genに書かれたロケールを生成します。
# locale-gen
生成されたかどうか以下のコマンドで確認します。
# eselect locale list
Available targets for the LANG variable:
[1] C
[2] C.utf8
[3] POSIX
[4] en_US.utf8
[5] C.UTF8 *
[ ] (free form)
en_US.utf8が生成されていることが確認できましたが、*印がついて使用されていない状態であるので、現在のロケールを変更します。
# eselect locale set 4
Setting LANG to en_US.utf8 ...
Run ". /etc/profile" to update the variable in your shell.
# eselect locale list
Available targets for the LANG variable:
[1] C
[2] C.utf8
[3] POSIX
[4] en_US.utf8 *
[ ] (free form)
環境設定を更新します。
# env-update && source /etc/profile && export PS1="(chroot) ${PS1}"
カーネルのビルド
以下のコマンドでカーネルソースを/usr/src/ディレクトリ内にインストールします。
# emerge --ask sys-kernel/gentoo-sources
インストールされたカーネルソースへlinuxというシンボリックリンクが作成されていることを確認します。
# ls -l /usr/src/linux
lrwxrwxrwx 1 root root 22 Dec 6 06:33 /usr/src/linux -> linux-5.4.80-gentoo-r1
では/usr/src/linuxへと移動し、カーネルをビルドするにあたって必要な設定をしていきます。
# cd /usr/src/linux
# make menuconfig
make menuconfigは、以下のようにコンソール上でメニュー形式でオプション項目が表示されます。

公式ハンドブックで必須のオプションを確認するのですが、ほとんどが設定済みであったため、新しく設定した部分は以下の場所だけになります。
Device Drivers --->
HID support --->
[*] Battery level reporting for HID devices
システムブートにUEFIを選択したので、UEFIのサポートを有効にします。
-*- Enable the block layer --->
Partition Types --->
[*] Advanced partition selection
[*] EFI GUID Partition support
ではカーネルのコンパイルとインストールをしていきます。以下のコマンドではまずmakeコマンドで、カーネルとカーネルモジュールのコンパイルをしています。それから、makeコマンドのmodules_installで、カーネルモジュールを適切なディレクトリにインストールしています。
# make && make modules_install
最後にカーネルを/bootディレクトリにインストールします。
# make install
/etc/fstabの編集
システム起動時、自動的に重要なパーティションをマウントできるように、/etc/fstabを編集していきます。fstab内の最初のフィールドにはUUIDを指定して、より安全にマウントできるようにします。
blkidでそれぞれのパーティションのUUIDを調べて、以下のようにfstabファイルを編集します。
# blkid
# vi /etc/fstab
UUID="F22E-FC9E" /boot vfat defaults,noatime 0 2
UUID="a80d75f2-c8aa-46cf-9d34-06ff0ccde7b3" / ext4 noatime 0 1
UUID="3122f9a9-85ef-4487-85fe-336ed57cb0f3" none swap sw 0 0
/dev/cdrom /mnt/cdrom auto noauto,user 0 0
:wq!
ネットワークの設定
新しい環境でもネットワークに自動的に接続できるようにdhcpクライアントをインストールします。
# emerge --ask net-misc/dhcpcd
rootパスワード設定
新しい環境(chrootしているこの環境)をインストール完了後は使用するので、この環境用のrootユーザのパスワードを設定する必要があります。これをやらないと、ログインできなくなります。
# passwd
システムログツールのインストール
初挑戦なので、とりあえずデフォルトの設定のままで利用できるsysklogdを選択して、デフォルトで起動するように設定します。
# emerge --ask app-admin/sysklogd
# rc-update add sysklogd default
cronのインストール
ハンドブックにより推奨されているため、インストールして、デフォルトで起動するように設定しておきます。
# emerge --ask sys-process/cronie
# rc-update add cronie default
ファイルインデックスの作成
ファイル検索をより高速にするため、mlocateをインストールしてインデックスを作成します。
# emerge --ask sys-apps/mlocate
sshdの設定
起動時にデフォルトでsshdが起動するように設定します。
# rc-update add sshd default
Grub2のインストール&設定
Grub2のemergeでyesを実行する前に、GRUB_PLATFORMS=”efi-64″が有効になっていることを確認して、emergeを実行します。デフォルトで有効になっているはずですが、これが有効でないとUEFIに対応できないようです。
# emerge --ask --verbose sys-boot/grub:2
---------(省略)----------
[ebuild N ] sys-boot/grub-2.04-r2:2/2.04-r2::gentoo USE="fonts nls themes -device-mapper -doc -efiemu -libzfs -mount -sdl (-test) -truetype" GRUB_PLATFORMS="efi-64 pc -coreboot -efi-32 -emu -ieee1275 -loongson -multiboot -qemu -qemu-mips -uboot -xen -xen-32 -xen-pvh" 7,957 KiB
Total: 4 packages (4 new), Size of downloads: 10,459 KiB
Would you like to merge these packages? [Yes/No]
以下のコマンドでGrubをインストールします。
# grub-install --target=x86_64-efi --efi-directory=/boot --removable
Installing for x86_64-efi platform.
Installation finished. No error reported.
grub-mkconfigコマンドで/boot/grub/brub.cfgに設定ファイルを作成します。
# grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.4.80-gentoo-r1
done
システムの再起動
ではchroot監獄から抜けて、全てのパーティションをアンマウントして再起動します。
# exit
# cd
# umount -l /mnt/gentoo/dev{/shm,/pts,}
# umount -R /mnt/gentoo
# reboot
VirtualBoxの設定
再起動しても仮想光学ディスクを取り除かないといけないので、一度シャットダウンさせ、VirtualBoxマネージャで以下のように空にします。

ちなみにこのままだと、このように起動に失敗します。

ではどうするかというと、VirtualBoxマネージャのシステム –> 拡張機能 –> EFIを有効化にチェックを入れます。そうすると無事に起動することができると思います。

screenfetch
rootユーザでパスワードを入力してログインできたら、#GentooInstallBattleで勝利したことを示すため、screenfetchコマンドを使用して、Gentooのロゴを表示させます。
# emerge app-misc/screenfetch
# screenfetch

最後に
以上でGentoo Linuxの最小限のインストールが完了しましたが、正直圧倒的にまだ理解が足りてないと思います。特にebuild、Portageの仕組みや使い方がいまいちなので、ebuildのファイルの中身を覗いてみたり、試行錯誤していこうと思います。
なかなか理解に時間がかかりそうですが、ある程度まで理解できたら、Linux from Scratchにチャレンジしていきます。
参考文献
Gentoo Linux amd64 ハンドブック: Gentoo をインストールする
標準テキスト CentOS7 構築・運用・管理パーフェクトガイド
Comments