3 # mkrescue - create a boot floppy or cd image with the current kernel
5 # Copyright 2001-2005 John Coffman
6 # Copyright 2010-2011 Joachim Wiedorn <ad_debian at joonet.de>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # set the version number on this command
29 # set the version of LILO required to run
34 log=$(pwd)/mkrescue.log
35 clog=$(pwd)/mkrescue.conf.log
41 usage: `basename $0` [--help]
42 `basename $0` [--version]
43 `basename $0` [--device <device>] [--fast] [--fs ext2|msdos|minix]
44 [--image <label>] [--install text|menu] [--keymap <keymap.ktl>]
45 [--initrd <file> --kernel <file>] [--append <string>]
46 [--root <device>] [--nocompact] [--noformat]
47 [--iso] [--size 1440|1200|2880|HD]
49 --device is the floppy drive; e.g., /dev/fd0
50 --fast specifies creation using a loopback device, which may be faster
51 --fs is the filesystem to make on the device; e.g., ext2
52 --help prints this helpfile
53 --iso create a bootable ISO image to burn to a CD-R or CD-RW
54 --keymap is the keyboard translation table; default to same as lilo.conf
55 --noformat bypasses creation of a new filesystem on device
56 --nocompact omits lilo map file compaction
57 --size is assumed to be 1440 (1.44M), unless 1200 or 2880 is specified
58 HD may be specified for ISO images
59 --image specifies the label of the kernel/initrd if not the default
60 --install 'text' is the default for floppies, 'menu' for ISO images
61 --initrd and --kernel are the initial ramdisk & kernel files
62 --append is a string used to specify kernel options
63 --root is the root filesystem for the boot floppy; e.g., current
64 --version prints the version number of `basename $0`
65 --debug provide verbose output and pausing after defined steps
67 Used without any arguments, `basename $0` will use the default kernel in
68 /etc/lilo.conf, the companion initrd (if any), and the specified root
69 filesystem to make a bootable rescue floppy.
75 if [ $debug != false ]; then
77 config=$(pwd)/lilo.conf
83 if [ ! -r "$config" ] ; then
84 echo "$0: Cannot read the configuration file $config (are you root?)"
92 tmpbase="`mktemp -dt $(basename $0).XXXXXXXXXX`" || {
93 echo "Could not create temporary directory."; exit 1
95 mount="$tmpbase/mkrescue-flp"
96 mfile="$tmpbase/mkrescue-emu"
97 mtemp="$tmpbase/mkrescue-tmp"
99 touch "$mfile" "$mtemp"
122 VERSION=$($lilo -V | awk '{print $3}' | sed -e "s/[^a-zA-Z0-9.]//g")
124 NVERSION=$(echo $VERSION | sed "s/\\./ /g")
126 DASH=$(echo $VERSION | sed "/-/s/.*-//" )
127 if [ "$DASH" = "$VERSION" ]; then
130 NVERSION=$(echo $NVERSION | sed "s/-.*//")
132 MAJOR=$(echo $NVERSION | sed "s/ .*//")
133 MINOR=$(echo $NVERSION | sed -e "s/$MAJOR //" -e "s/ .*//" )
134 if [ "$MINOR" = "$NVERSION" ]; then
137 REVISION=$(echo $NVERSION | sed "s/$MAJOR $MINOR //")
138 if [ "$REVISION" = "$NVERSION" ]; then
141 REVISION=$(echo $REVISION | sed "s/ .*//")
142 if [ "$MINOR" -gt 49 ]; then MINOR=$(expr $MINOR % 10); fi
144 if [ $debug = true ]; then
146 echo VERSION $VERSION
150 echo REVISION $REVISION
155 #if [ "$MAJOR" -lt "$major" \
156 # -o "$MINOR" -lt "$minor" \
157 # -o $REVISION -lt "$revision" ]
159 if [ "$REVISION" -lt "$revision" ]
162 #echo $REVISION lt $revision
164 if [ "$MINOR" -gt "$minor" ]
167 #echo $MINOR gt $minor
169 if [ "$MAJOR" -gt "$major" ]
172 #echo $MAJOR gt $major
174 if [ "$skip" = "true" ]
176 echo `basename $0` version $version
177 echo "LILO version $major.$minor.$revision (or newer) is required."
181 umount $mount 2>/dev/null
185 master=`mount | grep " / " | cut -d " " -f 1`
186 master=`echo $master | sed "s/part[0-9]*$/disc/"`
187 master=`echo $master | sed "s/[0-9]*$//"`
188 if [ ! -b $master ]; then master=`echo $master | sed "s/p$//"`; fi
189 if [ ! -b $master ]; then master="" ; fi
192 while [ $# -gt 0 ]; do
256 echo `basename $0` version $version
260 echo "unrecognized argument: " $1
268 if [ -z "$image" ]; then
269 # image=`cat /proc/cmdline | sed "s/.*BOOT_IMAGE=//" | sed "s/ .*//"`
270 image=`$lilo -C $config -v0 -w -I " " D`
273 if [ -z $kernel ]; then
274 kernel=`$lilo -C $config -v0 -w -I "$image" i`
275 if [ "$kernel" = "" ]; then exit 1;
276 elif [ $debug = "true" ]; then echo kernel = "$kernel";
280 if [ -z $root ]; then
281 root=`$lilo -C $config -v0 -w -I "$image" R`
282 if [ "$root" = "No root specified" ]; then
283 root=`grep </etc/fstab -v "^[ \t]*#" |
284 grep "[[:space:]]/[[:space:]]" | \
285 sed -e "s/^[ \t]*//" -e "s/[ \t].*//"`
286 if [ -z $root ]; then
287 root=`mount | grep " on / type" | sed "s/ .*//"`
289 if [ -z $root ]; then
290 echo "Cannot find mounted root partition"
291 echo "Using current root"
295 if [ $debug = true ]; then echo root = "$root";
299 if [ -z $initrd ]; then
300 initrd=`$lilo -C $config -v0 -w -I "$image" r`
301 if [ "$initrd" = "" ]; then exit 1;
302 elif [ $debug = "true" ]; then echo initrd = "$initrd";
305 if [ "$initrd" = "No initial ramdisk specified" ]; then initrd= ; fi
307 if [ -z $append ]; then
308 append=`$lilo -C $config -v0 -w -I "$image" a`
309 if [ "$append" = "" ]; then exit 1;
310 elif [ $debug = "true" ]; then echo append = \"$append\";
313 if [ "$append" = "No append= was specified" ]; then append= ; fi
315 if [ -z $keymap ]; then
316 keymap=`$lilo -C $config -v0 -w -I "$image" k`
317 if [ "$keymap" = "" ]; then exit 1;
318 elif [ $debug = "true" ]; then echo keymap = "$keymap";
322 if [ $isoimage = yes ]; then
324 if [ $size = 0 ]; then
326 elif [ $size = HD -o $size = hd ]; then
329 if [ $device = "/dev/fd0" ]; then
333 umount $device 2>/dev/null 1>/dev/null
336 if [ $size = 0 ]; then
340 if [ $size = 1200 ]; then
342 elif [ $size = 1440 ]; then
344 elif [ $size = 2880 ]; then
347 if [ -f $boot/diag1.img -a -f $boot/diag2.img ]; then
350 elif [ $size = $hdsize ]; then
353 cylinders=$(($size/$sectors/$heads*2))
354 if [ $size != $(($sectors*$heads*$cylinders/2)) ]; then
355 echo Internal error in HDsize
359 if [ -f $boot/diag1.img -a -f $boot/diag2.img ]; then
362 elif [ $size = HD -o $size = hd ]; then
363 echo "--size $size may only be used with the --iso option."
366 echo "--size must be 1200 or 1440; --size 1440 assumed."
371 if [ $fs != msdos -a $fs != ext2 -a $fs != minix ]; then
372 echo "illegal option: --fs" $fs
373 echo " must be either msdos or ext2 or minix"
377 if [ $fs = msdos ]; then
378 mountconfig=$mount/lilo.cnf
380 mountconfig=$mount/lilo.conf
383 if [ $debug = "true" ]; then
389 echo device = $device
391 echo kernel = $kernel
392 echo initrd = $initrd
393 echo append = \"$append\"
394 echo install = $install
395 echo format = $format
399 echo compact = $compact
400 echo keymap = $keymap
401 echo isoimage = $isoimage
402 echo master = $master
404 echo pause after parameter display
408 if [ ! -f $kernel ]; then
409 echo "Kernel file " $kernel " does not exist"
413 if [ ! -z $initrd ]; then
414 if [ ! -f $initrd ]; then
415 echo "Initial ramdisk file " $initrd " does not exist"
420 if [ $isoimage != yes ]; then
422 if [ -x /usr/bin/du ]; then
423 totalsize=`/usr/bin/du -Dc $kernel $initrd $keymap |tail -1 | awk '{ print $1 }'`
424 if [ "$totalsize" -gt "$size" ] ; then
425 echo "Sorry, the ramdisk, kernel and keymap don't fit in the floppy disk."
430 echo "Insert a blank floppy into $device"
431 echo "All information on this floppy will be destroyed"
432 echo "Press [Enter] to proceed, ^C to abort"
436 if [ "$fast" = fast ]; then
438 dd bs=1024 count=$size of=$mfile if=/dev/zero
441 if [ $size = $hdsize ]; then
443 bsize=$(($size-$sectors))
454 echo Partitioning HD "file (this will take a minute)"
455 fdisk -b 512 -S $sectors -H $heads -C $cylinders \
456 $mfile < $mtemp > /dev/null 2> /dev/null
460 losetup -d /dev/$loopback 2>/dev/null
461 losetup -d /dev/$looppart 2>/dev/null
462 losetup /dev/$loopback $mfile
463 losetup -o $(($sectors*512)) /dev/$looppart $mfile
466 echo Making filesystem
467 if [ "$fs" = ext2 ]; then
468 echo y | mkfs.$fs -N 24 -b 1024 $mpart $bsize
470 echo y | mkfs.$fs $mpart
472 echo Mounting filesystem
474 if [ $size != $hdsize ]; then
475 mount -t $fs -o rw,loop $mfile $mount
476 loopback=`mount | grep $mfile | sed -e "sX.*loop=/dev/XX" -e "s/).*//"`
478 mount -t $fs -o rw $mpart $mount
480 if [ $debug = true ]; then
483 disk="/dev/$loopback"
484 if [ $debug = true ]; then
490 if [ "$format" = "yes" ]; then
491 echo Formatting $device with $fs filesystem...
492 dd of=$device if=/dev/zero bs=512 count=1
493 if [ "$fs" = ext2 ]; then
494 mkfs -t $fs -N 24 -b 1024 $device 1>/dev/null 2>/dev/null
496 mkfs -t $fs $device 1>/dev/null 2>/dev/null
503 mount -t $fs -o rw $device $mount
510 cat > $mountconfig <<EOF
511 # Begin mkrescue $version configuration file
521 disk=$disk bios=$bios
522 sectors=$sectors heads=$heads cylinders=$cylinders
524 if [ $size = $hdsize ]; then
525 echo " max-partitions=7" >>$mountconfig
526 echo " partition=/dev/$looppart start=$sectors" >>$mountconfig
527 echo static-bios-codes >>$mountconfig
533 if [ "$master" != "" -a $isoimage = yes ]; then
534 echo "disk=$master" >>$mountconfig
535 echo " bios=$bios" >>$mountconfig
536 elif [ "$master" != "" -a $debug = true ]; then
537 echo "disk=$master" >>$mountconfig
538 echo " bios=$bios" >>$mountconfig
541 if [ $keymap != us.ktl ]; then
542 echo "keytable=lang.ktl" >>$mountconfig
545 if [ $isoimage = yes ]; then
546 echo "el-torito-bootable-CD" >>$mountconfig
549 echo " " >>$mountconfig
550 echo "image=linux" >>$mountconfig
552 if [ ! -z $initrd ]; then
553 echo " initrd=initrd" >>$mountconfig
556 if [ ! -z "$append" ]; then
557 echo " append=\"$append\"" >>$mountconfig
560 cat >> $mountconfig <<EOF
565 if [ "$master" != "" -a $isoimage = yes ]; then
566 cat >> $mountconfig <<EOF
573 if [ "$diag" = yes ]; then
574 cp -pv $boot/diag1.img $mount
575 cp -pv $boot/diag2.img $mount
576 cat >> $mountconfig <<EOF
583 echo >>$mountconfig "# End of mkrescue-generated configuration file"
585 if [ $isoimage = yes ]; then
586 comment="El-Torito bootable-CD will boot at end of timeout"
588 comment="floppy will boot in 15 seconds"
591 rm -rf $mount/lost+found
592 cat > $mount/message <<EOF
594 MKRESCUE version $version $comment
595 Use "boot: linux <options>" to enter kernel options
596 The root device is currently configured as root="$root"
599 echo `uname --sysname` `uname --release` > $mount/$(uname --release)
603 if [ $debug = true ]; then
606 echo "pause after writing lilo.conf & message ..."
610 echo "Copying files..."
611 if [ $keymap != us.ktl ]; then
612 cp -pv $keymap $mount/lang.ktl
615 if [ ! -z $initrd ]; then
616 cp -pv $initrd $mount/initrd
619 cp -pv $kernel $mount/linux
627 pushd $mount >/dev/null 2>/dev/null
628 if [ "$fast" = fast ]; then
629 bootcmd="-b /dev/$loopback"
632 echo Running $lilo ...
633 if [ $debug = true ]; then
635 cp -pvf $mountconfig $clog
637 echo $lilo -w+ -C $mountconfig $compact $bootcmd -v5
638 $lilo -w+ -C $mountconfig $compact $bootcmd -v5 || fast=error
640 echo $lilo -w+ -C $mountconfig $compact $bootcmd -v5 ">$log"
641 $lilo -w+ -C $mountconfig $compact $bootcmd -v5 >$log || fast=error
645 $lilo -C $mountconfig $compact $bootcmd || fast=error
647 popd >/dev/null 2>/dev/null
648 if [ "$fast" = error ]; then
658 if [ $fast = error ]; then
662 if [ $isoimage = yes ]; then
663 echo START MakeISOFS:
667 if [ $size = $hdsize ]; then
668 losetup -d /dev/$looppart
669 losetup -d /dev/$loopback
672 mv $mfile $mount/boot.bin
673 genisoimage $opt -J -R -T \
674 -V LILO_BOOT -A "Linux Boot CD created by LILO mkrescue" \
675 -b boot.bin -c boot.cat -o $out $mount
678 END MakeISOFS: output is in '$device'
681 The bootable CD can be burned with the 'cdrecord' or 'wodim' utility
682 using a command of the form:
684 cdrecord [<options>] [dev=<device>] $device
685 wodim [<options>] [dev=<device>] $device
688 elif [ "$fast" = fast ]; then
689 if [ $debug = true ]; then
690 echo Pause before transfering to $device
693 dd if=$mfile of=$device bs=1024