Linux From Scratchをqemuで実行する方法
Linux From Scratch
Linux From Scratchはaptとかyumとかdnfを使わずにあらゆるパッケージを自前でビルドしてlinuxを動かそうというものです。linux kernelの勉強のために触ってみたのですが、最後の最後でgrubというブートローダのホスト側の設定を変えなければならず、しかも起動するたびにパソコンを再起動しなければならないというめんどくささ、そしてググってみた感じではほかに記事がなかったのでqemuで実行できるようにしてみました。
環境
ホストマシン:Ubuntu 20.04
qemu-system-x86_64:QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.10)
Linux From Scratch(LFS):Version 10.0-systemd
10.LFS システムのブート設定のLinux-5.8.3まで作業が終わっていること
lfsフォルダは/home/lfs以下に置かれていることとする
$ ls ~/lfs
bin dev home lib64 media opt root sbin srv tmp var
boot etc lib linuxrc mnt proc run sources sys usr
イメージディスクの作成
当初はinitramfsでやろうと考えていましたが、initramfsは3GB程度の制限を受けてしまうため(sourceフォルダを除外すれば2GB程度に収まるがsourceを除外するのはなんだかもったいないと思った)ここではイメージディスクを作成します。
まず、空のイメージディスクを作成します。
dd if=/dev/zero of=disk.img bs=1G count=50
これで50GBのイメージファイルが作成されます。
ループバックデバイスの登録
先ほど作成したイメージファイルをループバックデバイスとして登録します。ループバックデバイスはファイルをあたかもデバイスとして扱えるようにする仕組みのことです。
sudo losetup /dev/loop20 disk.img
パーティションの作成
作成したイメージファイルにパーティションを作成します。
sudo parted /dev/loop20
実行すると以下のような表示になると思います。
GNU Parted 3.3
/dev/loop20 を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted)
この状態で以下を実行します。
mklabel msdos
mkpart primary fat32 1 512M
mkpart primary ext2 512M 100%
set 1 boot on
q
これでパーティションの作成が完了しました。
パーティションのデバイス登録
イメージディスクにパーティションを作成しましたので、次はそれぞれのパーティションをマウントしていきます。イメージディスクにパーティションが複数あるときはkpartxを使ってマウントしていきます。
sudo apt update
sudo install kpartx
sudo kpartx -a /dev/loop20
これで/dev/mapperにloop20p1(パーティション1)、loop20p2(パーティション2)がそれぞれできます。
パーティションのフォーマット
作成したパーティションをフォーマットしていきます。
sudo mkfs.fat -F32 /dev/mapper/loop20p1
sudo mkfs -t ext2 /dev/mapper/loop20p2
パーティションのマウント
フォーマットしたパーティションをマウントしてきます。
mkdir $(pwd)/mnt
sudo mount /dev/mapper/loop20p2 $(pwd)/mnt/
sudo mkdir $(pwd)/mnt/boot
sudo mount /dev/mapper/loop20p1 $(pwd)/mnt/boot
LFSのファイル群のコピー
sudo cp -r ~/lfs/* $(pwd)/mnt
grubのインストール
最後にgrubをインストールします。(ここをミスると下手をすればホストのgrubを上書きする恐れがあるのでミスはしないように)
sudo grub-install --target=i386-pc --root-directory=$(pwd)/mnt /dev/loop20
cat <<EOF | sudo tee $(pwd)/mnt/boot/grub/grub.cfg
# Begin /boot/grub/grub.cfg
set default=0
set timeout=5
menuentry "GNU/Linux, Linux 5.8.3-lfs-10.0-systemd" {
insmod ext2
set root=(hd0,1)
linux /vmlinuz-5.8.3-lfs-10.0-systemd root=/dev/sda2
}
EOF
sync
起動
qemuを使って起動します。
qemu-system-x86_64 -drive format=raw,file=disk.img -curses
終了するときはAlt+2を押した後、quitを入力
おまけ
今回はbiosによるブートをしています。EFIによるブートをするのであればefiパーティションを作ってgrub-installのtargetをi386-efiやx86_64-efiにすればいいと思われますが、まだ試してないのでわかりません。
また、ファイル作成時(例えばtouchコマンド)に
touch: a: Read-only file system
と怒られます。理由は探し中ですが、対処法として
mount -o rw,remount /
を入力すれば作成できるようになります。
Discussion