#title kexec-toolsを利用する UbuntuでSynapticパッケージマネージャでkexec-toolsをインストールすれば使えます。<
> 起動したいカーネルと利用したいinitramfs(initrd.img)を含むパーティションがマウントされていなければ、まず、マウントしてください。<
> 端末で {{{ kexec -l 起動したいカーネルの名前(フルパスで) --initrd=利用したいinitramfsの名前(フルパスで) --append="カーネルに渡したいオプション" }}} で次回の再起動後に利用するカーネルなどを設定できます。再起動せずにすぐに設定したカーネルを起動したい場合、 {{{ kexec -e }}} を実行すれば良いです。 <> == ubuntuのinitramfsにkexec-toolsを組み込む方法 == || ''' /!\ 最初に断っておきますが、以下の方法で作成したinitramfs(initrd.img)は、絶対に、Ubuntuがインストールされているパーティション(/にマウントされるパーティション)の/ディレクトリにはコピーしないでください。同名のシンボリックリンクがあるので、問題が生じる可能性があります。 また、以下の方法はカーネル2.6.31-17-generic, 2.6.31-20-generic, 2.6.32-21-generic, 2.6.32-21-generic-pae, 2-6-32-22-generic, 2.6.32-22-generic-paeのinitramfsに対して成功していますが、他のバージョンの場合にはうまく行かないかもしれません。'''他のバージョンでうまく行かない場合には、initramfs(initrd.img)の中身、特にinitとそれが利用するスクリプトを理解して適切に変更する必要があると思います。 || synapticなどで、kexec-toolsをインストールします。 「ホーム・フォルダ」にinitrd.imgの展開用のディレクトリ(ここではinit)を作成しておきます。 {{{ ~$ mkdir init }}} 展開用のディレクトリ(ここではinit)に移動します。 {{{ ~$ cd init }}} 現在使われているカーネルのバージョンのinitramfsを展開します。 {{{ ~/init$ gzip -dc /boot/initrd.img-$(uname -r) | cpio -i }}} kexecに必要な、/sbin/kexecと/lib/tls/i686/cmov/libc.so.6をinitの中にコピーします。 {{{ ~/init$ cp -p /sbin/kexec sbin/ ~/init$ mkdir -p lib/tls/i686/cmov ~/init$ cp -p /lib/tls/i686/cmov/libc.so.6 lib/tls/i686/cmov/ }}} ~/initの内容を再圧縮してintiramfsに戻します。 {{{ ~/init$ find .|cpio -H newc -o|gzip -9 > ../initrd.img }}} これで、ホームフォルダのinitrd.imgファイルは、kexecが利用できる状態になっています。 でも、これだけでは、chrootする前の環境で利用できる状態になっているだけで、通常はコマンドラインから作業はできません。つまり、kexecを利用して他の本来起動したいカーネルを起動することはできません。次の作業を行えば、本来起動したいカーネルを選択するメニューを表示させることができます。 <> === 改変されたinitrd.imgでkexecを利用するメニューを表示させるための方法 === || /!\ 注意:インストールされたUbuntuの/のパーティションと/bootのパーティションが別の場合、/vmlinuzと/inirtd.imgというシンボリックリンクが利用できず、また、/のパーティションの/bootにカーネルやinitramfsが存在しない(/bootのパーティションの/に存在する)ので、下記の方法を行っても起動できません。 || {{{ ~/init$ gedit ./init }}} で~/init/initを編集します。 以下3行 {{{ for conf in conf/conf.d/*; do [ -f ${conf} ] && . ${conf} done }}} を削除。 {{{ maybe_break }}} で始まる行を全て削除。 {{{ log_begin_msg "Mounting root file system..." }}} の行以降を全て削除。 以下を末尾に追記。 {{{ [ -d /mnt ] || mkdir -m 0755 /mnt echo ========================== echo "Please wait until all the device you want to boot is recognized and then push ENTER key." echo ========================== read a deviceslist=$(blkid|cut -d: -f1) okdeviceslist="" for a in $deviceslist do umount -l /mnt 2>/dev/null mount -t auto $a /mnt 2>/dev/null || continue if [ -e /mnt/vmlinuz -a -e /mnt/initrd.img ] then okdeviceslist="${okdeviceslist} $a" elif [ -n "$(ls /mnt/boot/ -1 2>/dev/null|grep vmlinuz)" ] then if [ -e /mnt/boot/initrd.img-$(ls /mnt/boot -1|grep vmlinuz|tail -n1|cut -c9-) ] then okdeviceslist="${okdeviceslist} $a" fi fi umount -l /mnt 2>/dev/null done i=0 echo ========================== echo "The device file names and information of partitions will be recognized and are shown below." echo for a in ${okdeviceslist} do echo $i":"$(blkid|grep "${a}:") i=$(expr $i + 1) done echo echo "Please type the number of the device file name of the root partition of Ubuntu you want to boot." readloop() { while [ a = a ] do read a if [ $a -ge 0 ] then if [ $? = 1 ] then echo "Please type number" continue elif [ $a -lt "$(echo $*|tr ' ' '\n'|wc -l)" ] then break else echo "Please type number smaller than $(echo $*|tr ' ' '\n'|wc -l)" continue fi echo "Please type number larger than 0 or 0" fi done } readloop ${okdeviceslist} device=$(echo ${okdeviceslist}|cut -d" " -f $(expr $a + 1)) echo "You selected $a:$device" mount -t auto $device /mnt }}} さらに、最新のカーネルのみで起動させれば良い場合には、以下の(1)の枠内を、複数のカーネルを自分で選択したい場合には以下の(2)の枠内を、それぞれ、末尾に追記する。 (1) {{{ if [ -e /mnt/vmlinuz -a -e /mnt/initrd.img ] then echo "Please enter commandline parameter to pass to kernel except root=... and ro" read a kexec -l /mnt/vmlinuz --append="root=UUID=$(blkid|grep "$device:"|sed -e "s/^.*UUID=\"//"|sed -e "s/\".*//") ro $a" --initrd=/mnt/initrd.img kexec -e exit 0 elif [ -n "$(ls /mnt/boot/ -1 2>/dev/null|grep vmlinuz)" ] then if [ -e /mnt/boot/initrd.img-$(ls /mnt/boot -1|grep vmlinuz|tail -n1|cut -c9-) ] then echo "Please enter commandline parameter to pass to kernel except root=... and ro" read a kexec -l /mnt/boot/$(ls /mnt/boot -1|grep vmlinuz|tail -n1) --append="root=UUID=$(blkid|grep "$device:"|sed -e "s/^.*UUID=\"//"|sed -e "s/\".*//") ro $a" --initrd=/mnt/boot/initrd.img-$(ls /mnt/boot -1|grep vmlinuz|tail -n1|cut -c9-) kexec -e exit 0 fi fi umount -l /mnt echo "DAMESSU! Please push ENTER key" PS1='(initramfs) ' /bin/sh -i /dev/console 2>&1 shutdown -r now exit 0 }}} (2) {{{ kernels1=$(ls /mnt/boot/ -1|grep vmlinuz) kernels="" i=0 for a in $kernels1 do if [ -n "$(ls -1 /mnt/boot/initrd.img-$(echo $a|cut -c9-))" ] then echo $i":"$(echo $kernels1|cut -d" " -f $(expr $i + 1)) i=$(expr $i + 1) kernels="$kernels $a" fi done echo "Please type the number of the kernel you want to boot." readloop ${kernels} kernel=$(echo ${kernels}|cut -d" " -f $(expr $a + 1)) echo "You selected $a:$kernel" echo "Please enter commandline parameter to pass to kernel except root=... and ro" read a kexec -l /mnt/boot/$kernel --append="root=UUID=$(blkid|grep "$device:"|sed -e "s/^.*UUID=\"//"|sed -e "s/\".*//") ro $a" --initrd=/mnt/boot/initrd.img-$(echo $kernel|cut -c9-) kexec -e umount -l /mnt echo "DAMESSU! Please push ENTER key" PS1='(initramfs) ' /bin/sh -i /dev/console 2>&1 shutdown -r now exit 0 }}} 追記するのは以上。以上のinitの編集作業が終わったら、テキストエディタ(gedit)で「保存」してから、テキストエディタを閉じる。 ~/initの内容から、initramfsを作って、~/initrd.imgという名前で保存。 {{{ ~/init$ find .|cpio -H newc -o|gzip -9 > ../initrd.img }}} 後は、最新のカーネル(/boot/vmlinuz-2.6.??-??-generic)と~/initrd.img(改変したinitrd.img)を起動時に認識できるパーティションにコピーして、それをカーネルローダー(例えばgrub4dosなど)で読み込むように設定すれば良いです。<
> grub4dosでの設定方法については[[https://wiki.ubuntulinux.jp/UbuntuTips/UsbInstall/BootUbuntuInUsbWithBiosWithoutSupportForUsb/Grub4dos|こちら]]をご覧ください。 <> ==== 改変したinitrd.imgを利用しての実際のUbuntuの起動方法 ==== 起動時にカーネルローダーで最新のカーネル(/boot/vmlinuz-2.6.??-??-generic)と改変したinitrd.imgを読み込ませると、 {{{ ========================== Please wait until all the device you want to boot is recognized and then push ENTER key. ========================== }}} と表示されるはずです。 USBメディアなどが認識されるまでに少し時間がかかる場合があります。認識されると画面上にメッセージが流れます。 しばらく待ってメッセージが流れなくなったらENTERキーを押してください。ずらずらといろいろなパーティションをマウントするためのメッセージが表示された後で、 {{{ ========================== The device file names and information of partitions will be recognized and are shown below. }}} と表示され、その後に {{{ 0:/dev/sd・・・ }}} などのように表示されるはずです。 起動したいUbuntuのインストールされたパーティションのラベルやUUIDを探すと良いです。 起動したいUbuntuのインストールされたパーティションの行の先頭の数字をタイプしてENTERキーを押してください。<
> (2)の場合、 {{{ 0:vmlinuz-・・・-generic }}} などのように表示されるはずです。 起動したいUbuntuのカーネルの行の先頭の数字をタイプしてENTERキーを押してください。<
> {{{ Please enter commandline parameter to pass to kernel except root=... and ro }}} と表示されたら、特別にカーネルに渡したいオプションを入力してください。たとえば、通常まともに表示できない場合に、xforcevesaなどを追記すると良いかもしれません。何もオプションが必要なければ、何も入力しないでください。 ENTERキーを押すと、Ubuntuが起動できるかもしれません。<
> 間違いがありましたら、バシバシ直してください。 = 謝辞 = このページの情報を作成するにあたり、 「 ubuntu の initramfs に kexec-tools を組み込む方法」については、 [[http://wikiwiki.jp/disklessfun/?board|disklessfun]] さんからご教示を賜りました。 また、以上の方法は、 grub4dos や kexec-tools, Ubuntu の開発者の方のご尽力があったからこそ実現できるものです。 この場をお借りして御礼申し上げます。