LoginSignup
14
15

More than 5 years have passed since last update.

ブータブルLinuxISOを手作りする

Last updated at Posted at 2018-08-04

Linuxのブータブルディスクの仕組みが気になったので手作りする方法を調べてみました。

ちなみにRedHat系OSであればloraxパッケージに含まれるlivemedia-creatorコマンドで簡単に作成できます。[1]

# livemedia-creator --make-iso --ks=/path/to/valid/kickstart.ks --no-virt

ブータブルISOについて

ISOの規格

ご存知のとおり、CD/DVDのフォーマットはISO9660で標準化されていますが、オリジナルの規格はファイル名等の制約が厳しいため様々な拡張規格が定義されています。
ISOファイルからのシステムブートはEl Toritoという拡張規格で定義されています。[2]

Linuxのブータブルディスク

LinuxシステムをISOからブートするにはISOLINUXという軽量ブートローダーを利用します。ISOLINUXはSYSLINUXに含まれるコンポーネントの一つです。

SYSLINUXはLinux向けの軽量ブートローダーを提供するプロジェクトで、いくつかのコンポーネントを含んでいます。例えばSYSLINUXコンポーネントはFAT32ファイルシステムから、PXELINUXはネットワークからシステムをブートするためのブートローダーを提供しています。[3]

例としてCentOS7のインストーラを見てみます。
CentOS7のインストーラーもCD/DVDからブートするLinuxシステムです。

インストーラーISOマウントすると(もしくはCentOSミラーの os/x86_64/ ディレクトリを開くと)isolinuxというディレクトリが含まれています。このディレクトリにはブートローダーである isolinux.bin、ブートメニューや起動オプション等を指定するisolinux.cfg、そのほかカーネルイメージvmlinuzや初期RAMディスクinitrd.imgが含まれています。

http://one.of.a.mirror/centos/7/os/x86_64/isolinux/
 boot.msg   2018-05-03 20:34    84   
 grub.conf  2018-05-03 20:34    281  
 initrd.img 2018-05-03 20:34    50M  
 isolinux.bin   2018-05-03 20:34    24K  
 isolinux.cfg   2018-05-03 20:34    3.0K     
 memtest    2016-11-05 16:27    186K     
 splash.png 2015-09-30 19:58    186  
 vesamenu.c32   2016-11-05 17:41    149K     
 vmlinuz    2018-04-20 16:57    5.9M     

ちなみにルートファイルシステムは LiveOS/squashfs.img にあります。
このイメージはsquashfsという圧縮された読み取り専用のファイルシステムです。
イメージの中には LiveOS/rootfs.img が含まれていて、これがルートファイルシステムのイメージファイルになります。
ルートファイルシステムにはAnaconda(Pythonの環境構築ツールではありません)というプログラムが含まれていて、このプログラムがハードディスクにLinuxをインストールします。[4]

ブータブルISOを手作りする

環境と必要なツール類

このサンプルはVirtualBox上にインストールしたCentOS 7.5の環境で実行しています。作成したISOの起動試験もVirtualBox上の仮想マシンイメージで行っています。

なお作業はすべてroot権限で行っています。

SELinuxを無効化します。

# setenforce 0

必要なパッケージをインストールします。

# yum install genisoimage squashfs-tools

ルートファイルシステムの作成

最初に作業ディレクトリを掘ります。これ以降、特に明示していない場合はこの作業ディレクトリ内でコマンドを実行しています。

TMP="/var/make-disk/"
mkdir -p $TMP
cd $TMP

ルートファイルシステムとなるイメージを作成してEXT4でフォーマットします。

# dd if=/dev/zero of=rootfs.img bs=1M count=1200
# mkfs.ext4 -F rootfs.img
# file rootfs.img 
rootfs.img: Linux rev 1.0 ext4 filesystem data, UUID=b1fd3d60-a9f0-4684-a45d-44332478be76 (extents) (64bit) (large files) (huge files)

ルートイメージをマウントして sys, proc, dev ディレクトリをマウントします。

# mkdir -p ./rootdir
# mount -o loop,rw,sync rootfs.img rootdir
# mkdir ./rootdir/{dev,proc,sys}
# mount -o bind /dev ./rootdir/dev
# mount -o bind /proc ./rootdir/proc
# mount -o bind /sys ./rootdir/sys

yumコマンドでルートイメージ内にLinuxの実行環境をインストールします。

yum install -y --installroot=${TMP}/rootdir --releasever=7 kernel coreutils passwd sudo

ユーザー cos を作成して root を無効化します。
cosにはパスワードなしでsudoを実行する権限を与えます。(パスワードなしでrootログインできるようにしてもいいですが...)

# chroot rootdir
(in chroot)# useradd cos
(in chroot)# passwd -d cos
(in chroot)# visudo
---
#%wheel ALL=(ALL)       ALL
(...omit)
%wheel  ALL=(ALL)       NOPASSWD: ALL
---
(in chroot)# usermod -aG wheel cos
(in chroot)# usermod -L root
(in chroot)# exit

他にもキーボードやタイムゾーン等必要に応じて設定します。

これでルートファイルシステムは出来上がりです。この後カーネルと初期RAMディスクを取り出すのでイメージはマウントしたままにしておきます。

ISOの作成

ディレクトリを掘ります。

# mkdir -p mkdir isoroot/{boot,isolinux}

SYSLINUXをダウンロードして、解凍したディレクトリにあるブートローダーisolinux.binと ldlinux.c32モジュールをコピーします。

# curl -LO https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz
# tar -xvzf syslinux-6.03.tar.gz
# cp -a syslinux-6.03/bios/core/isolinux.bin isoroot/isolinux/
# cp syslinux-6.03/bios/com32/elflink/ldlinux/ldlinux.c32 isoroot/isolinux/

isolinux.cfgを作成します。詳しい設定はSYSLINUXのWebページを参照してください。[5]

# vi isoroot/isolinux/isolinux.cfg
---
default basic0
label basic0
  kernel /boot/vmlinuz0
  append initrd=/boot/initrd0 root=live:CDLABEL=linux rootfstype=auto ro rd.live.image rhgb rd.luks=0 rd.md=0 rd.dm=0 
---

ルートファイルシステムにchrootしてISO用の初期RAMディスクを作成します。
既定で作成される初期RAMディスクには、ISOに含まれるルートファイルシステムをマウントするためのモジュールが含まれていないため、そのままでは使用できません。

# chroot ./rootdir
(in chroot)# dracut --xz --add "dmsquash-live convertfs pollcdrom" --omit plymouth --no-hostonly --no-early-microcode /boot/initrd0 `ls /lib/modules`
(in chroot)# exit

カーネルと初期RAMディスクをISOのディレクトリにコピーします。

# cp -a rootdir/boot/vmlinuz-3.10.0-862.9.1.el7.x86_64 ./isoroot/boot/vmlinuz0
# cp -a rootdir/boot/initrd0 ./isoroot/boot/initrd0

コピーしたらルートファイルシステムの/bootディレクトリにあるファイルは不要なので削除します。

# rm -rf rootdir/boot/*

rootファイルシステムイメージをアンマウントしてsquashfsで圧縮します。

# umount rootdir/sys
# umount rootdir/proc
# umount rootdir/dev
# umount rootdir
# mkdir -p squashfsroot/LiveOS
# mv rootfs.img squashfsroot/LiveOS/
# mksquashfs squashfsroot squashfs.img

作成したsquashfsイメージをISOのLiveOSディレクトリにコピーします。

# mkdir isoroot/LiveOS
# mv squashfs.img isoroot/LiveOS/

最終的にISOに含まれるファイルはこんな感じです。

./isoroot/
./isoroot/boot
./isoroot/boot/vmlinuz0
./isoroot/boot/initrd0
./isoroot/isolinux
./isoroot/isolinux/isolinux.bin
./isoroot/isolinux/ldlinux.c32
./isoroot/isolinux/isolinux.cfg
./isoroot/LiveOS
./isoroot/LiveOS/squashfs.img

最後にISOファイルを作成します。

# cd isoroot
# mkisofs -o ../cos7.iso -R -J -T -V linux -b isolinux/isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table .

使用しているmkisofsの主要なオプションは次のような感じです

  • -o 出力ファイル名
  • -R, -J, -T ISO9660標準ではサポートされないファイル名を扱うためのオプションです。
  • -V LABEL ISOのラベルを指定しています。上のサンプルでは "linux" を指定していますが、このディスクのラベルはisolinux.cfgに定義した"root=live:CDLABEL=linux"と対応させておく必要があります。
  • -b El Toritoブートローダーであるisolinux.binを指定します。

作成したISOイメージを適当な仮想マシンにアタッチして起動してみてください。
手順に誤りがなければCentOS 7が起動してcosユーザーでログインできるはずです。


[1]https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/installation_guide/sect-disk-image-installation-automatic
[2]https://ja.wikipedia.org/wiki/ISO_9660
[3]https://www.syslinux.org/wiki/index.php?title=The_Syslinux_Project
[4]https://fedoraproject.org/wiki/Anaconda
[5]https://www.syslinux.org/wiki/index.php?title=Config

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15