主に以下の流れで作成する。
- Linux Kernelのイメージのインストール
- rootfsの作成
- QEMUでのテスト
- USBメモリへのインストール
Linux Kernelのビルド
https://kernel.org/ からインストールする。インストールしたバージョンは6.19.11。
Macのアーキテクチャはx86_64では無いのでDockerを使用してビルドする。Dockerコマンドを実行するディレクトリに、ダウンロードしてきたLinuxの .tar.gz ファイルを配置する。
docker volume create linux-build
docker run -it -v linux-build:/work ubuntu:24.04
コンテナ内でビルドツールをインストールする。
apt update
apt install -y build-essential flex bison bc libelf-dev libssl-dev wget
カーネルをインストールして、ビルドする。
cd /work
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.19.11.tar.xz
tar xf linux-6.19.11.tar.xz
cd linux-6.19.11
make defconfig
make -j4
BusyBoxのビルド
BusyBoxの1.36.1をビルドする。
先程のDockerコンテナに入り、ビルドツールをインストールする。
apt update
apt install -y build-essential flex bison bc libelf-dev libssl-dev wget cpio
BusyBox(1.36.1)をインストールする。
cd /work
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
設定でライブラリを静的リンクにする設定をした後に、ビルドをする。
make defconfig // 初期設定にする
apt install libncurses5-dev libncursesw5-dev // curses.hのインストール
// 設定画面に移行する
// Settings -> Build static binaryにチェック
// Networking Utilities -> tcのチェックを外す
make menuconfig
make install -j4
起動後ルートファイルシステムになるファイルを作成する
cd _install
find . | cpio -o --format=newc > ../rootfs.img
QEMUでのテスト
Dockerコンテナ内でビルドした2つのファイルをローカルにコピーする。
docker cp <コンテナ名>:/work/linux-6.19.11/arch/x86/boot/bzImage ./bzImage
docker cp <コンテナ名>:/work/busybox-1.36.1/rootfs.img ./rootfs.img
以下のコマンドを実行することで、Linux Kernel + BusyBoxの環境にアクセスできる。
qemu-system-x86_64 -kernel bzImage -initrd rootfs.img -append "root=/dev/ram rdinit=/bin/sh"
USBメモリへのインストール
パーティションの作成
UbuntuにUSBを指して、lsblk コマンドを使用した後に出た出力で USB と思われるドライブのパスを調べる。
私の場合は、sda というディスクの中に sda1 というパーティションがあることが分かった。
sda 8:0 1 7.5G 0 disk
└─sda1 8:1 1 7.5G 0 part /media/totosuki/09D4-6C68
USBメモリのパーティションがマウントされている場合は、アンマウントする。
sudo umount /dev/sda1
fdisk コマンドを使用してインタプリタ的に、パーティションを作成する。
sudo fdisk /dev/sda
// 以下の順に設定を行っていく
g # GPTパーティションテーブル作成
n # 新規パーティション (EFI用)
1 # パーティション番号
# (Enterでデフォルト)
+512M # サイズ
t # タイプ変更
1 # EFI System
n # 新規パーティション (Linux用)
2 # パーティション番号
# (Enter)
# (Enter 残り全部)
w # 書き込み
lsblk でパーティションができているか確認をする。
2つパーティションを作成したので、sda1 と sda2 が出ていたら成功。
sda 8:0 1 7.5G 0 disk
├─sda1 8:1 1 512M 0 part
└─sda2 8:2 1 7G 0 part
ファイルを実際にフォーマットする。
sudo mkfs.fat -F32 /dev/sda1
sudo mkfs.ext4 /dev/sda2
ファイルをマウントする。
sudo mount /dev/sda2
/mnt sudo mkdir -p /mnt/boot/efi
sudo mount /dev/sda1 /mnt/boot/efi
lsblk で正しくマウントができているか確認をする。
sda 8:0 1 7.5G 0 disk
├─sda1 8:1 1 512M 0 part /mnt/boot/efi
└─sda2 8:2 1 7G 0 part /mnt
ビルドデータのコピー
ビルドデータをUSBメモリ(今回のファイルシステム名だとsda2)にコピーする。
sudo cp /path/to/bzImage /mnt/boot/vmlinuz
sudo cp /path/to/rootfs.img /mnt/boot/
GRUBのインストール
grub-efi-amd64 をインストールする。
sudo apt install grub-efi-amd64
GRUBをUSBに入れる。コマンドの詳細は grub-installのオプション にて説明している。
sudo grub-install --target=x86_64-efi --efi-directory=/mnt/boot/efi --boot-directory=/mnt/boot --removable
GRUBの設定ファイルを作成
以下の内容を、/mnt/boot/grub/grub.cfg を手動で作る。
set timeout=5
set default=0
menuentry "My Linux" {
echo "START LOADING LINUX KERNEL!!!!!"
linux /vmlinuz rdinit=/init
initrd /rootfs.img
}
PCで起動する
アンマウントしてUSBを取り外す。/mnt ディレクトリ内に居るとアンマウントできない点に注意。
sudo umount /mnt/boot/efi
sudo umount /mnt
sync
以下の手順で Linux Kernel を起動する。
- USBを差し込み、電源を入れる
- BIOS/UEFI 設定画面に入る(今回の中古PCの場合F2連打)
- Secure Bootを無効にする
- ブート順序をUSBファーストにする。
GRUBメニューが出て「My Linux」を選べば、カーネルと initramfs が読み込まれて起動するはず!!