[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[plamo:17775] Re: INITRDでCD-ROMで起動する手法で行き詰まり?



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

exit
Title: Bootable CD memo.

ブータブル CD

HDD, FDD を用いずに使用できる ブータブル CD を作成する.

参考文献

man ページ

cdrecord(1), initrd(4), mkisofs(8),

カーネル文書

Documentation/initrd.txt, Documentation/kernel-parameters.txt, Documentation/ramdisk.txt, Documentation/filesystems/tmpfs.txt,

Linux Howto

Bootdisk-HOWTO, Building-Minimal-Linux, CD-Writing-HOWTO, CDROM-HOWTO, Diskless-HOWTO, NFS-Root, NFS-Root-Client, Remote-Boot, ext-root-mini-HOWTO,

起動メカニズムの概要

下で説明するように, 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) による通常の起動手順に入る.

Boot/Root デバイス

CD 上のファイルは書き込みできないので, 書き込み動作が必要な部分は RAM(/dev/ram 又は tmpfs) 上に置く必要がある. 書き込み動作が必要な部分は /etc(ld.so.cashe, mtab など), /tmp, /var, /dev(tty* など).

そこで, 2通りの方法が考えられる.

フロッピ起動の rootfs をそのまま使い, 必要なものは CD にリンクする

krenel オプション: initrd=initrd.gz root=/dev/ram

CD を / としてマウントする

書き換えられる部分は メモリ上のディスク(tmpfs 又は ram)に置く.
krenel オプション: initrd=initrd.gz root=/dev/hdc

Knoppix の例

rootfs をそのまま使い, 必要なものは CD にリンクしている.
* dev,etc,mnt,proc : rootfs
* home, var  : /ramdisk に マウント( tmpfs ).
*/tmp  /var/tmp にリンク
* bin,sbin,lib,opt,sbin,usr: /cdrom 内にリンク  

ブートフロッピ

FloppyFw は構成が簡潔で改造が容易なのでこれを参考にする.

フロッピーのイメージファイル

ブートローダとして lilo, grub, syslinux などを利用できる. また, カーネル自身のブート機能を用い, カーネルと initrd.gz だけを dd で直に書き込んでも良い. 多分, syslinux を用いるのが最も簡潔.

以下のように, 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

カーネル vmlinuz

起動時に必要なものは kernel に組み込んでおく. 特に以下に注意する. Loopback device support, RAM disk support, Initial RAM disk (initrd) support, Virtual memory file system support (former shm fs). ramdisk のサイズは initrd で用いる ディスクサイズ以上としておく.

initrd のファイルシステム

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

linuxrc

initrd で起動した場合 /linuxrc が実行される.

/dev

/dev は /dev/MAKEDEV で作成. cp -dpR /dev fdimage_dir としても良い. 最低限,次のファイルは必要: console, kmem, mem, null, ram, tty1.

/bin

BusyBox 形式になっている.

CD に入れるツール類の選定

動作中の Linux システムから, 必要なものをとってくる. /usr を除外すると 20M 程度の容量となる. これを元にして必要なディレクトリ/コマンドを作りこむ.
#!/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

CD 用に書き換えが必要なもの

CD を / とする.
/var : /var に tmpfs を用いる.
/etc/fstab :  cdrom を / とするなど.
/etc/rc.d/* : tmpfs に /var 以下のディレクトリを作成
/lib/modules : /var に置く.
/dev : /initrd に置く
/etc : /initrd に置く
/proc : /initrd に置く
/tmp : /var/tmp を用いる

/var

/var/run/utmp ファイルや /var/log ディレクトリが存在しない場合, 一部のシステムプログラム(login 等)は文句を言ってきます. そこで次のようにしておきます:
mkdir -p /mnt/var/{log,run}
touch /mnt/var/run/utmp

ldconfig

ldconfig は使わず LD_LIBRARY_PATH を用いる事もできます. (ld.so(8) 環境変数.)
LD_LIBRARY_PATH=/usr/X11/lib:/usr/local/lib
export LD_LIBRARY_PATH
ldconfig は /etc/ld.so.cache を作成します.

/etc

動作時に書き換えたいものもあるので, 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

/lib/modules

kernel の作成時にmodules をインストールするときに INSTALL_MOD_PATH 変数を適当に修正する.

make -e INSTALL_MOD_PATH=/lib modules_install

modules.dep などが /lib/modules/(version)/* に書き込まれる. (depmod(1) 参照.)

/etc/fstab

syslinux.cfg, linuxrc の初期化, /etc/fstab の / をあわせること

CD 作成手順

CD の iso9660 イメージ作成

mkisofs -b eltorito.img -c boot.cat -R -v -V KCCT_CD -o iso9660.img root-dir
eltorito.img はブートフロッピのイメージである.

CD-R への書き込み

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

テスト時の注意

CD-R に入れる前に, フロッピーから HDD をブートしてみる. initrd 側: linuxrc の初期設定, syslinux.cfg CD-R 側: /etc/fstab

References
[plamo:17771] Re: INITRDでCD-ROMで起動する手法で行き詰まり?, FUNABARA Masao
[plamo:17773] Re: INITRDでCD-ROMで起動する手法で行き詰まり?, K.Kodama
[plamo:17774] Re: INITRDでCD-ROMで起動する手法で行き詰まり?, FUNABARA Masao

[検索ページ] [メール一覧]
Plamo ML 公開システム