EFI stubなArch Linuxのインストール
QEMU上の仮想マシンにEFI stubなArch Linuxをインストールする。 ここでのホストはUbuntu 16.04.4 TLSとする。 なお[1][2][3][4]を参考にした。
OVMFのダウンロードとArch Linuxのインストールディスクのダウンロード
最初にOVMFをダウンロードして解凍する。 OVMFはTianoCoreをベースにした仮想マシン向けのUEFI実装である。
$ wget https://www.kraxel.org/repos/jenkins/edk2/edk2.git-ovmf-x64-0-20180508.84.g7cd8a57599.noarch.rpm
$ rpm2cpio edk2.git-ovmf-x64-0-20180508.84.g7cd8a57599.noarch.rpm | cpio -idmv
$ cp usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd .
$ cp usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd .
Arch Linuxのインストールディスクをダウンロードする。
$ wget http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/iso/2018.05.01/archlinux-2018.05.01-x86_64.iso
インストール先のディスクイメージを作成する。
$ qemu-img create -f raw arch-amd64.img 32G
仮想マシンの起動と設定
インストールディスクから起動する。 これ以降は仮想マシンでの操作となる。
$ qemu-system-x86_64 -enable-kvm -k ja -m 2048 -localtime -drive if=pflash,format=raw,readonly,file=OVMF_CODE-pure-efi.fd -drive if=pflash,format=raw,file=OVMF_VARS-pure-efi.fd -hda arch-amd64.img -net nic,model=e1000 -net user -cdrom archlinux-2018.05.01-x86_64.iso -boot d
キーボードレイアウトを設定。
# loadkeys jp106
gdisk
でパーティションを作成。
ここでは/dev/sda1を512MBのEFIパーティション、
/dev/sda2を残りのすべての容量としたLinuxパーティションとした。
# gdisk /dev/sda
Command (? for help):o
Command (? for help):n
Permission number: 1
First sector :
Last sector : +512M
Hex code or GUID : ef00
Command (? for help):n
Permission number: 2
First sector :
Last sector :
Hex code or GUID : 8300
最後に書き込みを行う。
Command (? for help):w
各パーティションをフォーマット
# mkfs.vfat -F32 /dev/sda1
# mkfs.ext4 /dev/sda2
それぞれをマウント。
# mount /dev/sda2
# mkdir -p /mnt/boot
# mount /dev/sda1 /mnt/boot
ダウンロードのミラーサイトを設定。
# nano /etc/pacman.d/mirrorlist
システムのインストール。
# pacstrap -i /mnt base base-devel
fstabの生成。
# genfstab -U -p /mnt >> /mnt/etc/fstab
localeの設定。
# locale-gen
# echo LANG=en_US.UTF-8 > /etc/locale.conf
# export LANG=en_US.UTF-8
キーボードマップの設定。
# echo KEYMAP=jp106 > /etc/vconsole.conf
localtimeの設定。
# rm /etc/localtime
# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# hwclock -u -w
ホスト名の設定。
# echo "arch-vm" > /etc/hostname
DHCPクライアントの設定。
# systemctl enable dhcpcd.service
パスワードの設定。
# passwd
GRUB2の代わりにefibootmgr
でEFI Variableを設定。
# efibootmgr -d /dev/sda -p 1 -c -L "Arch Linux" -l /vmlinuz-linux -u "root=dev/sda2 rw initrd=initramfs-linux.img"
# efibootmgr -v
exitしてhalt。
# exit
# halt
以下で正しく起動することを確認。
$ qemu-system-x86_64 -enable-kvm -k ja -m 2048 -localtime -drive if=pflash,format=raw,readonly,file=OVMF_CODE-pure-efi.fd -drive if=pflash,format=raw,file=OVMF_VARS-pure-efi.fd -hda arch-amd64.img -net nic,model=e1000 -net user
EFI stubなLinux kernelのビルド
先の説明でインストールしたArch LinuxはEFI stubとなっている。 ここでは、ホストでLinux kernelをビルドしそれを仮想マシンにインストールしてみる。
Linuxカーネルのビルド
カーネルをダウンロードする。
$ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git --branch v4.17 --depth 1
ホストのconfigをコピーして多少の修正を行い、ホスト上でビルドする。
make menuconfig
でCONFIG_EFI_STUB=y
となっていることを確認する。
make
するときのjob数はホストのCPUのコア数に応じて変更する。
$ cp /boot/config-4.15.0-33-generic .config
$ make menuconfig
$ make -j9
Linux kernelの仮想マシンへのインストール
仮想マシンのディスクイメージをマウントする。
# /sbin/kpartx -av arch-amd64.img
# mount /dev/mapper/loop0p2 /mnt
ホストでビルドしたカーネルを仮想マシンにインストールする。
# make INSTALL_MOD_PATH=/mnt modules_install
# mkdir -p /mnt/var/tmp
# cp System.map /mnt/var/tmp
# cp arch/x86_64/boot/bzImage /mnt/var/tmp
# umount /mnt
最後に仮想マシン上でホストでビルドしたbzImageとSystem.mapをコピーし、 initramfsを生成する。
# cp -f /var/tmp/bzImage /boot/vmlinuz-linux
# cp -f /var/tmp/System.map /boot/System.map
# mkinitcpio -c /etc/mkinitcpio.conf -g /boot/initramfs-linux.img
最後に再起動し、ビルドしたバージョンのカーネルであることを確認する。