From: FUNABARA Masao <l07steps@milk.freemail.ne.jp> Subject: [plamo:17774] Re: INITRDでCD-ROMで起動する手法で行き詰まり? Date: Tue, 18 Feb 2003 16:13:49 +0900 > FUNABARA です。 > 興味があるので、作成手順のメモと、シェルスクリプトを見てみたいです。 > お願いします。 ちょうど今作業中で, まとまりが無くて長いので気が引けますが... 作業しながらメモっているので, 記述に矛盾があるかもしれません. あと, 書いて欲しいことがあったら, 云って下さい, どっちみち, 文書に作業記録をまとめる事になっているので.... ディレクトリ構成 # ls -1 cdr-root/ CDイメージ作成作業用 floppy/ フロッピイメージ作成用 linux@ linux-2.4.20.cdr/ カーネル作成用 # ls -1 floppy bootdisk/ フロッピに書き込む内容 fd-setup.sh* floppy.img フロッピイメージ floppy.img.0 フロッピイメージ: MSDOS フォーマット initrd-disk/ initrd の内容 # ls -1 floppy/bootdisk/ floppy.msg* initrd.gz ldlinux.sys* syslinux.cfg* vmlinuz # ls -1 floppy/initrd-disk/ bin/ FloppyFw からとってきた BusyBox など dev/ etc/ lib/ linuxrc* mnt/ proc/ sbin@ # ls -1 cdr-root/ iso9660.img CD イメージ完成品 root/ CD に書き込む内容 root-setup.sh* # ls -1 -l cdr-root/root 通常の / 以下をちょっと改造 リンクに注目 合計 2140 drwxr-xr-x 2 root root 4096 12月 15日 12:31 bin/ lrwxrwxrwx 1 root root 10 2月 17日 07:46 dev -> initrd/dev -rw-r--r-- 1 root root 1474560 2月 18日 08:02 eltorito.img lrwxrwxrwx 1 root root 12 2月 17日 07:47 etc -> initrd/etc-r drwxr-xr-x 2 root root 4096 2月 17日 11:53 home/ drwxr-xr-x 2 root root 4096 2月 16日 04:48 initrd/ drwxr-xr-x 2 root root 4096 2月 18日 09:00 lib/ drwxr-xr-x 2 root root 4096 2月 16日 04:48 mnt/ drwxr-xr-x 2 root root 4096 2月 16日 10:36 mnt2/ drwxr-xr-x 4 root root 4096 2月 18日 08:59 opt/ drwxr-xr-x 2 root root 4096 2月 18日 07:28 proc/ drwxr-xr-x 2 root root 4096 12月 28日 23:25 sbin/ lrwxrwxrwx 1 root root 7 2月 17日 07:48 tmp -> var/tmp drwxr-xr-x 2 root root 4096 2月 17日 11:53 usr/ drwxr-xr-x 2 root root 4096 2月 17日 14:31 var/ -rw-r--r-- 1 root root 659778 2月 16日 09:46 vmlinuz ファイルの内容 # cat floppy/initrd-disk/linuxrc # hal91's initfile (/linuxrc), the bootup script of the system # VERSION=1.4 # echo "Booting floppy image" PATH="/bin" TERM=linux ignoreeof=10 no_exit_on_failed_exec=yes export PATH TERM ignoreeof umask 022 echo -n "mounting proc: " /bin/busybox mount -t proc /proc /proc echo "Generating links. (Thanks to busybox.lineo.com)" /bin/busybox --install -s mount -t iso9660 /dev/hdc /mnt cp -a /mnt/opt/etc etc-r umount /mnt exec ash umount /proc exit # cat floppy/bootdisk/ floppy.msg initrd.gz ldlinux.sys syslinux.cfg vmlinuz bash-2.05a# cat floppy/bootdisk/syslinux.cfg #serial=ttyS0 default kcctipc display floppy.msg label kcctipc kernel vmlinuz append initrd=initrd.gz root=/dev/hdc 作業手順: fd-setuo.sh で ブートフロッピイメージを作ります. root-setup.sh CP_ROOT で 動作中の Linux から CD の母型を作成します. 手でちょっと修正が必要ですが... root-setup.sh で CD の iso9660 イメージを作成します. cdrecord -scanbus cdrecord -v -dummy dev=2,0 speed=4 iso9660.img でCD を焼きます.(パラメータはシステム依存) -- Kouji KODAMA, kdm@kobe-kosen.ac.jp
#!/bin/sh # Use as root because of mount/umount MNT=/mnt # mount point of floppy-fw image INITRD_DIR=initrd-disk INITRD_IMG=initrd FLOPPY_DIR=bootdisk FLOPPY_IMG=floppy.img # target image file FLOPPY_DEV=/dev/sda # floppy device: /dev/fd0(standard floppy) or /dev/sda(USB floppy) LINUX=../linux KERNEL=${LINUX}/arch/i386/boot/bzImage MKE2FS_IMG(){ dd if=/dev/zero of=${INITRD_IMG} bs=1k count=6000 mke2fs -v -F -m0 -N 3000 ${INITRD_IMG} tune2fs -c0 -i0 ${INITRD_IMG} } CP_INITRD(){ mount -o loop -t ext2 ${INITRD_IMG} ${MNT} cd ${INITRD_DIR} cp -a bin ${MNT} cp -a /dev ${MNT} cp -a etc ${MNT} cp -a lib ${MNT} cp -a linuxrc ${MNT} cp -a mnt ${MNT} cp -a proc ${MNT} cp -a sbin ${MNT} cd .. umount ${MNT} gzip --best ${INITRD_IMG}; mv ${INITRD_IMG}.gz ${FLOPPY_DIR} } CP_FD(){ cp ${FLOPPY_IMG}.0 ${FLOPPY_IMG} syslinux ${FLOPPY_IMG} mount -o loop -t msdos ${FLOPPY_IMG} ${MNT} cp ${KERNEL} ${FLOPPY_DIR}/vmlinuz cd ${FLOPPY_DIR} cp syslinux.cfg ${MNT}/syslinux.cfg cp initrd.gz ${MNT} cp vmlinuz ${MNT} cp floppy.msg ${MNT} cd .. umount ${MNT} } MKE2FS_IMG CP_INITRD CP_FD case $1 in dd) dd if=${FLOPPY_IMG} of=${FLOPPY_DEV} ;; *) exit;; esac exit ## end
#!/bin/sh CDR_WORK=/home/kdm/kinds/cdr FLOPPY=${CDR_WORK}/floppy LINUX=${CDR_WORK}/linux ROOT_DIR=${CDR_WORK}/cdr-root/root # BOOT_IMG=${FLOPPY}/floppy.img KERNEL=${LINUX}/arch/i386/boot/bzImage # KERNEL=${FLOPPY}/bootdisk/vmlinuz # OPT_DIR=opt RAM_DIR=initrd CP_ROOT(){ mkdir ${ROOT_DIR} mkdir ${ROOT_DIR}/${OPT_DIR} mkdir ${ROOT_DIR}/${RAM_DIR} cp -a /bin ${ROOT_DIR} # /bin ln -s ${RAM_DIR}/dev ${ROOT_DIR}/dev # /dev cp -a /etc ${ROOT_DIR}/${OPT_DIR} # /etc ln -s ${RAM_DIR}/etc-r ${ROOT_DIR}/etc cp -a /sbin ${ROOT_DIR} # sbin mkdir ${ROOT_DIR}/home # home cp -a /lib ${ROOT_DIR} # lib mkdir ${ROOT_DIR}/mnt # mnt mkdir ${ROOT_DIR}/proc # /proc ln -s var/tmp ${ROOT_DIR}/tmp # tmp mkdir ${ROOT_DIR}/usr # /usr cp -a /var ${ROOT_DIR}/${OPT_DIR} # /var ln -s /${TMP_DIR}/var ${ROOT_DIR}/var # put modules under /var cp -a /lib/modules ${ROOT_DIR}/${OPT_DIR}/var rm -r ${ROOT_DIR}/lib/modules ln -s ../var/modules ${ROOT_DIR}/lib/modules cp -a ${BOOT_IMG} ${ROOT_DIR}/eltorito.img # boot image cp -a ${KERNEL} ${ROOT_DIR}/vmlinuz # kernel } MK_ISO_IMG(){ true;# cp -a ${BOOT_IMG} ${ROOT_DIR}/eltorito.img cp -a ${KERNEL} ${ROOT_DIR}/vmlinuz mkisofs -b eltorito.img -c boot.cat -R -v -V KCCT_CD -o iso9660.img ${ROOT_DIR} } CD_RECORD(){ #SCSI-ID と LUN を調べ, dev=device の項に用いる cdrecord -scanbus #試験焼き込み cdrecord -v -dummy dev=2,0 speed=4 iso9660.img } case $1 in root) CP_ROOT ;; record) CD_RECORD;; *) MK_ISO_IMG;; esac exitTitle: Bootable CD memo.
下で説明するように, CD の iso9660 の ElTorito ブート, フロッピーのブートローダ, initrd での暫定ルートファイルシステムの起動手順, init によるルートファイルシステムの起動手順 などを連結して Linux システム起動させる.
"El Torito" 形式のブータブル CD を作成する. CD 内の ブートフロッピのイメージを エミュレーションモードで起動することになる.
起動フロッピ内では, initrd による 2段階起動を用いる.(initrd(4) を参照.) kernel オプションで initrd=initrd.gz をあたえ, initrd の内容を初期(暫定的な)ルートファイルシステムとしてマウントして起動する.
initrd のファイルシステム上の /linuxrc が実行される. 様々な初期設定などを行う.
/linuxrc を終了することで, 通常時ルートファイルシステムがマウントされる. これは, kernel オプションとして root=... であたえる. また, proc ファイルシステムの /proc/sys/kernel/real-root-dev というファイルに ルートファイルシステムのデバイス番号を書きこんでやると、 initrd を終了した際, そのデバイスをルートファイルシステムとしてマウントする.
initrd で使った暫定版のルートファイルシステムは 実際のルートファイルシステムになるパーティションの /initrd というディレクトリにマウントされる.
/sbin/init(/etc/inittab) による通常の起動手順に入る.
そこで, 2通りの方法が考えられる.
krenel オプション: initrd=initrd.gz root=/dev/ram
krenel オプション: initrd=initrd.gz root=/dev/hdc
* dev,etc,mnt,proc : rootfs * home, var : /ramdisk に マウント( tmpfs ). */tmp /var/tmp にリンク * bin,sbin,lib,opt,sbin,usr: /cdrom 内にリンク
以下のように, FAT 形式のフロッピーイメージを作る.
fdformat /dev/fd0h1440 mformat /dev/fd0 dd if=/dev/fd0 of=eltorito.img
syslinux をインストールし, vmlinuz, initrd.gz, syslinux.cfg, floppy.msg をフロッピイメージに置く.
syslinux eltorito.img mount -o loop -t msdos eltorito.img /mnt cp -a vmlinuz /mnt cp -a initrd.gz /mnt cp -a syslinux.cfg /mnt cp -a floppy.msg /mnt umount /mnt
syslinux.cfgファイルの内容
default linux # file for boot message display floppy.msg label linux kernel vmlinuz # kernel option append initrd=initrd.gz root=/dev/hdc
ext2 形式のイメージファイルを作成する.
dd if=/dev/zero of=initrd bs=1k count=6000 mke2fs -v -F -m0 -N 3000 initrd tune2fs -c0 -i0 initrd
initrd に /dev, /linuxrc などを作りこむ.
mount -o loop -t ext2 initrd /mnt cp -a linuxrc /mnt cp -a /dev /mnt ...../etc /bin などを作る. umount /mnt
gzip 圧縮し initrd.gz を作る.
gzip --best initrd
#!/bin/sh ROOT_DIR=cdr-root OPT_DIR=opt RAM_DIR=initrd KERNEL=/vmlinuz # 作業環境とターゲットのカーネルが異なる場合適当に書き換える BOOT_IMG=eltorito.img # ブートフロッピーのイメージファイル mkdir -p ${ROOT_DIR} mkdir -p ${ROOT_DIR}/${OPT_DIR} mkdir -p ${ROOT_DIR}/${RAM_DIR} cp -a /bin ${ROOT_DIR} # dev は initrd のものを使う ln -s ${RAM_DIR}/dev ${ROOT_DIR}/dev # etc は CD に格納しておいて initrd のrootfsにコピーして使う cp -a /etc ${ROOT_DIR}/${OPT_DIR} ln -s ${RAM_DIR}/etc-r ${ROOT_DIR}/etc cp -a /lib ${ROOT_DIR} cp -a /sbin ${ROOT_DIR} # home は後で NFS マウントする予定 mkdir -p ${ROOT_DIR}/home mkdir -p ${ROOT_DIR}/mnt # proc は initrd のものを使う ln -s ${RAM_DIR}/proc ${ROOT_DIR}/proc # tmp は /var/tmp を使う ln -s var/tmp ${ROOT_DIR}/tmp # /usr は後で NFS マウントする予定 mkdir -p ${ROOT_DIR}/usr # var は CD に格納しておいて tmpfs をマウントし,コピーして使う. cp -a /var ${ROOT_DIR}/${OPT_DIR} mkdir ${ROOT_DIR}/var cp -a ${BOOT_IMG} ${ROOT_DIR}/eltorito.img cp -a ${KERNEL} ${ROOT_DIR}/vmlinuz
/var : /var に tmpfs を用いる. /etc/fstab : cdrom を / とするなど. /etc/rc.d/* : tmpfs に /var 以下のディレクトリを作成 /lib/modules : /var に置く. /dev : /initrd に置く /etc : /initrd に置く /proc : /initrd に置く /tmp : /var/tmp を用いる
mkdir -p /mnt/var/{log,run} touch /mnt/var/run/utmp
LD_LIBRARY_PATH=/usr/X11/lib:/usr/local/lib export LD_LIBRARY_PATHldconfig は /etc/ld.so.cache を作成します.
動作時に書き換えたいものもあるので, CD に置いておき, linuxrc スクリプトで cp する.
1. ブート/ルートシステムに設定しなければならないファイル: rc.d/* -- システムの起動と実行レベル変更のスクリプト fstab -- マウントするファイルシステムのリスト inittab -- init プロセス (起動時の最初のプロセス)のパラメータ. 2. ブート/ルートシステム用に短くしておいた方が良いファイル: passwd -- ユーザ,ホームディレクトリのリスト group -- ユーザグループ shadow -- ユーザのパスワード.このファイルは無いかもしれない. termcap -- 端末機能データベース: linux-console の項目だけ最小限の inittab 例:
id:2:initdefault: si::sysinit:/etc/rc 1:2345:respawn:/sbin/getty 9600 tty1 2:23:respawn:/sbin/getty 9600 tty2
kernel の作成時にmodules をインストールするときに INSTALL_MOD_PATH 変数を適当に修正する.
make -e INSTALL_MOD_PATH=/lib modules_install
modules.dep などが /lib/modules/(version)/* に書き込まれる. (depmod(1) 参照.)
syslinux.cfg, linuxrc の初期化, /etc/fstab の / をあわせること
mkisofs -b eltorito.img -c boot.cat -R -v -V KCCT_CD -o iso9660.img root-direltorito.img はブートフロッピのイメージである.
SCSI-ID と LUN を調べ, dev=device の項に用いる.
cdrecord -scanbus
試験焼き込みで確認する.
cdrecord -v -dummy dev=2,0 speed=4 iso9660.img
焼き込み.
cdrecord -v dev=2,0 speed=4 iso9660.img