#!/bin/sh <<@ LILO QUICK INSTALLATION Version 22.5 of 15-Dec-2003 ----------------------- --------------------------- This installation script installs LILO and generates the configuration file /etc/lilo.conf. It uses safe defaults for most configuration options. Please read the documentation (preferably the more complete LaTeX version, doc.tex) before making changes to the configuration generated by QuickInst. To run QuickInst, simply type ./QuickInst If the normally used root partition is mounted below root (e.g. during system installation), set the environment variable ROOT to the name of the directory on which the root partition is mounted and run QuickInst, e.g. ROOT=/root ./QuickInst A subshell can be spawned at each prompt. Type ! to get an interactive shell that has to be left with exit . Type !command args ... to execute a command and immediately return to QuickInst. QuickInst can only be used to install LILO on IDE (AT-BUS) or SCSI hard disks. The LILO version must be 22 or later, the kernel should be 2.0.4 or later. Owners of some disk adapters may have to create a DISK section (see section "Disk geometry" in the accompanying documentation) to describe the disk geometry. WARNING: QuickInst may get confused if you're running it in a directory that contains a mixture of old and new LILO distributions. To be safe, always extract new LILO distributions in their own, new directory. ------------- End of description. What follows is program code. ------------- @ CFG_SUFFIX=/etc CFG_DIR=$ROOT$CFG_SUFFIX CFG_FILE=$CFG_DIR/lilo.conf BOOT_SUFFIX=/boot BOOT_DIR=$ROOT$BOOT_SUFFIX SBIN_DIR=$ROOT/sbin locate() { var=$1 while shift && [ ! -z "$1" ]; do for p in `echo $PATH | sed 's/:/ /g'`; do if [ -x $p/$1 ]; then eval $var=$p/$1 return 0 fi done done return 1 } probe() { [ ! -z "`dd if=$1 bs=1 count=1 2>/dev/null | tr '\0' x`" ] return } bootflag() { [ "XY" = "`(dd of=/dev/null bs=510 count=1; dd bs=2 count=1 | tr -c '\125\252' . | tr '\125\252' XY) <$1 2>/dev/null`" ] return } krnltype() { if [ "YX" = "`(dd bs=2 count=1 | tr -c '\001\013' . | tr '\001\013' XY) \ <$1 2>/dev/null`" ]; then echo compound else echo image fi } get() { while true; do echo -n "$1 " if [ -z "$3" ]; then echo -n "(no default) " else echo -n "[$3] " fi read line line="`echo "$line" | sed 's/^ *\([^ ]\(\|.*[^ ]\)\) *$/\1/'`" if [ -z "$line" ]; then if [ -z "$3" ]; then echo "No default, please specify a value." continue fi line=$3 fi if [ "x$line" = "x!" ]; then cat <<EOF Starting a sub-shell. Type exit to return. EOF ${SHELL:-sh} echo continue fi if echo "$line" | grep '^!' >/dev/null; then sh -c "`echo \"$line\" | sed 's/^!//'`" else eval $2="$line" break fi done } yesno() { while true; do get "$1" line $2 if echo "$line" | egrep -i '^y(|e(|s))$' >/dev/null; then return 0 fi if echo "$line" | egrep -i '^no?$' >/dev/null; then return 1 fi echo "YES or NO, please." done } askinitrd() { idef="" for nn in /initrd /boot/initrd $ROOT/initrd $ROOT/boot/initrd; do if [ -f $ROOT/$nn ]; then idef=$nn break fi done if yesno "Does this kernel need an inital ramdisk?" no; then get "Initial ramdisk" initrd "$idef" if [ -f $initrd ]; then echo " initrd = $initrd" >>$CFG_FILE.tmp return 0 else echo "$initrd does not exist." echo "You must specify an absolute path" echo "# initrd = $initrd # file not found" >>$CFG_FILE.tmp return 1 fi fi } ##################################################### # start of the actual script ##################################################### echo if [ $ROOT/etc/lilo = `pwd` ]; then cat <<EOF You can't run QuickInst in /etc/lilo ! Please cd to the directory that contains your LILO source files and try again. EOF exit 1 fi if id | grep 'uid=0(' >/dev/null; then : ; else echo "You probably have to be root to install LILO." echo if yesno "Try to install LILO anyway ?" no; then : ; else echo exit 1 fi echo fi badlib="" if [ "`echo 'X(Y)' | sed 's/\(X\)(Y)/\1/'`" != "X" ]; then echo "Your sed doesn't behave like sed." badlib=y fi if [ "`echo 'X(Y)' | grep '^X(Y)'`" != "X(Y)" ]; then echo "Your grep doesn't behave like grep." badlib=y fi if [ "`echo 'X(Y)' | egrep '^(X)\(Y\)'`" != "X(Y)" ]; then echo "Your egrep doesn't behave like egrep." badlib=y fi if [ ! -z "$badlib" ]; then echo "Your libraries might be broken." echo exit 1 fi cat <<EOF QuickInst configures LILO and installs it on your hard disk. It should only be used for first-time installations, _not_ to update or modify an existing installation of LILO. It will _not_ generate a valid installation with versions of LILO below 22. The installation procedure can be interrupted by pressing ^C at any time. When at a prompt, a sub-shell can be invoked with the exclamation mark. EOF if yesno "Continue ?" yes; then : ; else echo exit 0 fi echo replace="" if [ -d $BOOT_DIR -a \( -f boot.b -o -f first.S \) ]; then cat <<EOF A directory $BOOT_SUFFIX already exists. If you're installing a new version of LILO now, QuickInst has to replace the old files with the new ones. EOF if yesno "Replace old files ?" yes; then replace=y fi echo fi if [ -f $ROOT/etc/lilo/install -a ! -L $ROOT/etc/lilo/install -a \ "$replace" != "y" ]; then cat <<EOF /etc/lilo/install is a regular file and not a symbolic link. It should be a symbolic link to /sbin/lilo (see INCOMPAT for details). EOF if yesno "Replace install by a link ?" yes; then ln -sf $SBIN_DIR/lilo $ROOT/etc/lilo/install fi echo fi noinst="" if [ -f $CFG_DIR/disktab ]; then if [ "#|" = "`sed 1q <$CFG_DIR/disktab`" ]; then cat <<EOF $CFG_DIR/disktab is a Shoelace-style parameter table. It is incompatible with LILO and most likely obsolete. EOF if yesno "Remove $CFG_DIR/disktab ?" yes; then rm -f $CFG_DIR/disktab else if yesno "Proceed anyway ?" no; then cat <<EOF Okay, but QuickInst won't automatically invoke LILO at the end of the configuration session, because you have to get rid of disktab first. EOF noinst=y else echo Terminating exit 1 fi fi echo fi fi echo if [ ! -f $BOOT_DIR/boot.b -o ! -z "$replace" ]; then if [ ! -f boot.b ]; then if [ ! -f first.S ]; then cat <<EOF LILO is not installed and I don't know how to make it. Please cd to the directory where your LILO source lives and try again. EOF exit 1 fi if [ ! -f /usr/include/linux/config.h ]; then cat <<EOF The kernel header files appear to be missing. Please install them, then try QuickInst again. EOF exit 1 fi if [ ! -f /usr/include/linux/autoconf.h ]; then cat <<EOF (Creating dummy /usr/include/linux/autoconf.h) EOF touch /usr/include/linux/autoconf.h fi cat <<EOF Making LILO ... EOF if make; then : ; else exit; fi echo fi cat <<EOF Installing LILO ... EOF if make install; then : ; else exit; fi echo fi if [ ! -x $SBIN_DIR/lilo ]; then cat <<EOF $SBIN_DIR/lilo is missing. Don't know how to proceed ... EOF exit 1 fi version="`$SBIN_DIR/lilo -V 2>/dev/null | sed 's/LILO version \(0\.\)\?//' | sed 's/\..*//'`" # echo LILO version $version is installed if [ -z "$version" ]; then cat <<EOF Incompatible version of LILO. Expecting 22 (or later), found 10 or older. EOF exit 1 fi if [ "$version" -lt 22 ]; then cat <<EOF Incompatible version of LILO. Expecting 22 (or later), found $version EOF exit 1 fi #if [ ! -x ./activate ]; then # cat <<EOF #activate is not in the current directory. Please cd to your LILO source #directory and run QuickInst again. #EOF #fi if [ -d $ROOT/etc/lilo -a ! -x $ROOT/etc/lilo/install ]; then ln -s $SBIN_DIR/lilo $ROOT/etc/lilo/install fi if [ -f $CFG_FILE ]; then cat <<EOF There is an existing configuration file: "$CFG_FILE" EOF if yesno "Do you wish to generate a new \"$CFG_FILE\"" no ; then : else echo echo "Running $SBIN_DIR/lilo" ... echo if $SBIN_DIR/lilo ; then echo else cat <<EOF Errors were noted in the running of the newly installed LILO with the old configuration file. You will have to edit the file and re-run $SBIN_DIR/lilo to install the new boot loader. Exiting ... EOF fi exit fi fi dev="`find /dev -maxdepth 1 -type b -name '[hs]da' | sed 's,/[hs]da$,,;1q'`" if [ -z "$dev" ]; then cat <<EOF (Can't locate hda or sda device in /dev or in a subdirectory or it. Assuming disk devices live in /dev) EOF dev="/dev" else echo "(Disk devices live in $dev)" fi echo echo "Gathering configuration data ..." second=/dev/sdb if [ -L $dev/hda ]; then cat <<EOF $dev/hda is a symbolic link. Assuming your first disk is $dev/sda EOF first=$dev/sda if probe $dev/sdb; then second=$dev/sdb fi else if probe $dev/hda; then first=$dev/hda if probe $dev/hdb; then second=$dev/hdb else if probe $dev/sda; then second=$dev/sda fi fi else if probe $dev/sda; then first=$dev/sda if probe $dev/sdb; then second=$dev/sdb fi else cat <<EOF Unable to determine what your first disk is. (Tried $dev/hda and $dev/sda, but none of them appears to exist.) Sorry, this is a fatal error. EOF exit 1 fi fi fi root="" if locate path rootdev rdev setroot; then root=`$path | awk '{ print $1 }'` echo echo "(/ is mounted on $root)" fi boot="" if echo $root | grep "^${first}[1-4]*\$" >/dev/null; then boot=$root fi cat <<EOF Please specify the name of the device where the LILO boot sector should be stored. (Suggested locations are the Linux root partition or the MBR of your first drive). EOF while true; do get "Device name" inp $boot if echo "$inp" | grep / >/dev/null; then : ; else inp="/dev/$inp" fi if echo "$inp" | egrep \ "^${first}\$|^${first}[1-4]\$|^${second}\$|^${second}[1-4]\$" \ >/dev/null; then if true -o probe "$inp"; then boot=$inp break else cat <<EOF No such device exists. Type !ls {$first,$second}[1-4] for a list of possible names. EOF fi else cat <<EOF This is not a valid device name. Try names like $first or ${first}1 EOF fi done on_second= curr_first=$first curr_second=$second if echo "$boot" | grep "$second" >/dev/null; then cat <<EOF You have decided to put the LILO boot sector on your SECOND disk ($second). This may indicate an unusual configuration. Please indicate your future plans by selecting one of the following choices: keep if you do not intend to change the disk configuration, i.e. your current first disk stays first and your current second disk stays second. swap if you intend to swap $first and $second after installing LILO, either by physically swapping the two disks, or by configuring your BIOS to make them appear as if they had changed places. (The latter choice needs BIOS support.) remove if you intend to remove your current first disk ($first) after installing LILO and to use your current second disk as the first disk. EOF while true; do get "Your choice" line keep if echo "$line" | egrep -i '^k(|e(|ep?))$' >/dev/null; then break fi if echo "$line" | egrep -i '^r(|e(|m(|o(|ve?))))$' >/dev/null; then on_second=remove first=$second second= break fi if echo "$line" | egrep -i '^s(|w(|ap?))$' >/dev/null; then on_second=swap tmp=$first first=$second second=$tmp break fi echo "KEEP, REMOVE, or SWAP, please." done fi if [ ! -z "$on_second" ]; then cat <<EOF Please note that the configuration generated in this session is only valid for the current hardware configuration. If you are removing or (physically) swapping disks, you will have to update the configuration in order to reflect the changed system configuration. You can do this either by running QuickInst again or directly by editing the configuration file $CFG_FILE EOF fi if [ "$boot" = "$first" ]; then cat <<EOF You are about to install LILO on your MBR. If there are other operating systems on your hard disk, LILO will act as a boot manager for them. You have to specify each operating system in your LILO configuration. (More about this later.) EOF fi if echo "$boot" | grep '^$first[1-4]$' >/dev/null; then if [ "`dd if=$first bs=1 count=4 skip=2 2>/dev/null | \ tr -c 'LIO' '?'`" = "LILO" -o \ "`dd if=$first bs=1 count=4 skip=6 2>/dev/null | \ tr -c 'LIO' '?'`" = "LILO" ]; then cat <<EOF There appears to be a LILO boot sector on $first. Because you're installing LILO's boot sector on a regular partition now, it is very likely that the old boot sector will no longer start correctly. Unless you're very sure of what you're doing, you should therefore replace it by a "standard" MBR before attempting to boot from the hard disk. (E.g. use MS-DOS 5.0's FDISK /MBR or, better, $SBIN_DIR/lilo -M $first ) EOF fi fi disk=`echo $boot | sed 's/[1-4]$//'` oldboot=`$SBIN_DIR/lilo -A $disk 2>/dev/null` newboot="" if [ $boot != "$oldboot" -a ! -z "`echo "$boot" | sed 's|'$dev'/[sh]d.||'`" ]; then echo if [ -z "$oldboot" ]; then echo "There's no active partition on $disk" msg="Activate $boot ?" else echo "Currently active partition of $disk is $oldboot" msg="Change it to $boot ?" fi if yesno "$msg"; then newboot=`echo $boot | sed 's,'$dev'/[sh]da,,'` cat <<EOF Partition $newboot of $disk will be made active as soon as the LILO installation is complete. EOF else cat <<EOF Please don't forget to configure the boot manager you are using to boot LILO from $boot. EOF fi fi kernel="" for n in /vmlinuz /boot/vmlinuz /linux /boot/linux /zImage /boot/zImage; do if [ -f $ROOT/$n ]; then kernel=$n break fi done cat <<EOF Please specify the name of the kernel image file you want to boot by default. You may list the $ROOT/boot directory with: !ls $ROOT/boot/vm* EOF while true; do get "Default kernel" inp $kernel if [ -f "$ROOT$inp" ]; then if echo "$inp" | grep '^/' >/dev/null; then kernel=$inp break else echo "Use only absolute path names, e.g. /linux" fi else echo "No such file." fi done cat <<EOF >$CFG_FILE.tmp # LILO configuration created by QuickInst 22.5 `date | tr -s x ' '` boot = $boot prompt # always expect prompt timeout = 150 # wait 15 seconds vga = normal # force sane state lba32 # 'linear' is deprecated delay = 30 # delay 3 seconds if there is a stored command line #serial = 0,1200n8 # uncomment to use COM1 too read-only # initailly mount roots r/o EOF if [ "$on_second" = swap ]; then cat <<EOF >>$CFG_FILE.tmp disk = $curr_first # disks will be swapped bios = 0x81 disk = $curr_second bios = 0x80 EOF fi if [ "$on_second" = remove ]; then cat <<EOF >>$CFG_FILE.tmp disk = $curr_first # disk will be removed inaccessible disk = $curr_second bios = 0x80 EOF fi cat <<EOF >>$CFG_FILE.tmp root = current # use "current" root `krnltype $kernel` = $kernel EOF if [ "`echo $kernel | sed 's,/\([^/]*\)$,\1,'`" != "linux" ]; then echo " label = linux" >>$CFG_FILE.tmp fi # add any initrd, if needed askinitrd echo if yesno "Define additional kernels ?" no; then default="" for n in $kernel.old /vmlinux.old /boot/vmlinuz.old /linux.old \ /boot/linux.old /zImage.old /boot/zImage.old; do if [ -f $ROOT/$n ]; then default=$n break fi done cat <<EOF Specify the names of additional kernels now. Use "done" (without the quotes) to stop adding kernels. EOF while true; do get "Kernel" inp $default if [ done = "$inp" ]; then break fi if echo "$inp" | grep '^/' >/dev/null; then echo "`krnltype $inp` = $inp" >>$CFG_FILE.tmp if [ ! -f $ROOT$inp ]; then echo "File doesn't exist now. - Making entry optional." echo " optional" >>$CFG_FILE.tmp fi askinitrd else echo "Use only absolute path names, e.g. /linux" fi default="done" done fi if [ "$boot" = "$first" ]; then cat <<EOF If you want to boot other operating systems than Linux from your hard disk, you should configure them now. LILO will take over the entire boot process, so any currently installed partition switchers or boot managers will stop to work. (If this scares you, just hit ^C and read the manual.) EOF fi echo if yesno "Define additional operating systems (e.g. MS-DOS) ?" no; then cat <<EOF Specify the names of devices that contain boot sectors of additional operating systems now. You might want to run fdisk or efdisk to list the partition table(s) of your hard disk(s) in order to obtain the device names. Use "done" (without the quotes) to stop adding operating systems. EOF default="" default_lbl=dos while true; do get "Device name" inp $default if [ done = "$inp" ]; then break fi if echo "$inp" | grep '^'$dev'/[hs]d[ab][1-4]$' >/dev/null; then if probe "$inp"; then if bootflag $inp; then loader="" if echo "$inp" | egrep "^${second}[1-4]\$" >/dev/null; then echo "It's on your second disk. Is this ..." if yesno "... OS/2 ?"; then loader="os2_d.b" else if yesno "... OS using the BIOS (e.g. DOS) ?"; then loader="chain.b" fi fi fi ( echo "other = $inp" echo -n " table = " echo $inp | sed 's/[1-4]$//' if [ ! -z "$loader" ]; then echo " loader = $BOOT_DIR/$loader" fi ) >>$CFG_FILE.tmp get "Label" inp $default_lbl default_lbl="" default="done" echo " label = $inp" >>$CFG_FILE.tmp else echo "$inp does not have a valid boot signature." fi else cat <<EOF No such device exists. Type !ls $dev/[hs]d[ab][1-4] for a list of possible names. EOF fi else echo "Expecting names like $dev/hda1, $dev/sda3, etc." fi done if [ -z "$default_lbl" ]; then cat <<EOF In order to choose the desired kernel or operating system, hold down a shift key at boot time, when LILO displays "LILO", until the prompt "boot:" appears. Then enter the label name. You can get a list of available names by pressing [Tab] (at the boot prompt). EOF fi fi if [ -f $CFG_FILE ]; then cat <<EOF An old version of the configuration file $CFG_FILE already exists. QuickInst will proceed as follows: - rename $CFG_FILE to $CFG_FILE.old - copy the new configuration file to $CFG_FILE Type !cat $CFG_FILE.tmp if you want to check the new configuration file. EOF if yesno "Proceed ?" yes; then mv $CFG_FILE $CFG_FILE.old else cat <<EOF Leaving the new configuration file in $CFG_FILE.tmp EOF exit fi fi mv $CFG_FILE.tmp $CFG_FILE if [ ! -z "$noinst" ]; then cat <<EOF LILO is now configured. However, automated installation is not possible now, because you still have an incompatible $CFG_DIR/disktab file. Please remove that file or specify an alternate name for the disk parameter table in $CFG_DIR/lilo.conf before trying to run $SBIN_DIR/lilo EOF exit fi cat <<EOF Ready to install LILO's boot sector on your hard disk. Type !cat $CFG_FILE if you want to check the configuration file. EOF if yesno "Test LILO installation now ?" yes; then echo outfile=${TMPDIR:-/tmp}/out$$ errflag=${TMPDIR:-/tmp}/err$$ if [ -f $errflag ]; then rm $errflag fi ( if $SBIN_DIR/lilo -t 2>&1 then : ; else touch $errflag fi ) | tee $outfile if [ -f $errflag ]; then rm $errflag if egrep 'geo_query_dev HDIO_|: Got bad geometry' <$outfile >/dev/null then cat <<EOF LILO is unable to obtain geometry information for your SCSI disk. Please create a DISK section in the configuration file in which the necessary parameters are described. See also section "Disk geometry" in the accompanying documentation. EOF exit fi cat <<EOF Something went wrong. Verify your input and try to minimize the complexity of the settings, e.g. by omitting additional kernels and operating systems. EOF exit fi if grep '^Warning: ' <$outfile >/dev/null; then cat <<EOF The following warning messages may indicate some potential problems with your configuration. The boot sector has not been changed yet. EOF grep '^Warning: ' <$outfile echo fi rm $outfile echo if yesno "Install LILO now ?" yes; then cat <<EOF You see now the output of the map installer with verbose progress reporting enabled. It will list all items that are installed for booting. Additionally, if there are have been warnings, they will be repeated again. EOF if $SBIN_DIR/lilo -v; then : ; else cat <<EOF Something went wrong, sorry. Verify your input and try to minimize the complexity of the settings, e.g. by omitting additional kernels and operating systems. EOF exit fi fi if [ ! -z "$newboot" ]; then $SBIN_DIR/lilo -A $disk $newboot fi fi echo echo "Done." echo