Inicio arrow Artículos arrow Linux arrow mkbootdisk, o cómo crear un disquete de arranque
Menú Principal
Lo más leído
Consigue Firefox
Usuarios
993 registrados
1 hoy
5 esta semana
138 este mes
Último: gabity...
Formulario de acceso



... Regenerar clave
... Registro
mkbootdisk, o cómo crear un disquete de arranque Imprimir E-Mail
viernes, 02 de junio de 2006

A través de este micro-documento aprenderemos a utilizar la herramienta mkbootdisk para crear un disquete que nos permita arrancar el sistema en una situación crítica o, simplemente, iniciar el mismo con el nuevo kernel que acabamos de descargar.


Usando la herramienta

mkbootdisk es un guión en bash que suele incluirse en una instalación por defecto de sistemas Red Hat o Fedora. Dicho programa se encargará de realizar todos los pasos necesarios para la creación de un disquete de arranque, herramienta imprescindible en determinadas situaciones que nos permitirá arrancar un ordenador desde un disquete con un sistema linux limpio.

En primer lugar, tenemos que tener claro cuál es el dispositivo de acceso a nuestra disquetera. En los sistemas linux, dicho dispositivo suele ser, casi en todos los casos /dev/fd0 y para nuestros fines, no puede estar montado. Si no estamos seguros, siempre podemos teclear lo siguiente en la consola:

[root@server ~]# umount /dev/fd0
umount: /dev/fd0: not mounted

A continuación, listaremos las versiones del núcleo que tenemos instaladas en nuestro sistema. Para ello, haremos uso de la siguiente instrucción:

[root@server ~]# ls /lib/modules
2.6.11-1.27_FC3  2.6.16-1.2096_FC5  2.6.16-1.2111_FC5  2.6.16-1.2122_FC5

En este caso, la salida nos ha mostrado cuatro versiones distintas del núcleo instaladas. Con estos datos, ya podemos ejecutar (como root) el comando mkbootdisk de la siguiente manera:

[root@server ~]# mkbootdisk 2.6.16-1.2111_FC5 --device /dev/fd0
Insert a disk in /dev/fd0. Any information on the disk will be lost.
Press <Enter> to continue or ^C to abort:

Tras pulsar la tecla Intro, el disquete será rellenado con los datos necesarios para ejecutar un arranque desde el mismo, siendo eliminada toda información existente en el soporte.


El guión

Como referencia, vamos a incluir a continuación la versión del script 1.5.2, incluida en Fedora en el paquete  mkbootdisk-1.5.2-5.2:

#!/bin/bash

# mkbootdisk
#
# Written by Erik Troan < Esta dirección de correo electrónico está protegida contra los robots de spam, necesita tener Javascript activado para poder verla >

pause=yes
unset kernel
device=/dev/fd0
unset verbose
unset kernelargs
unset mountopts
unset isoimage
unset realdev
size=1440
failed=0

MOUNTDIR=`mktemp -d /tmp/mkbootdisk.XXXXXX`
PATH=/sbin:$PATH
export PATH

VERSION=1.5.2

usage () {
    cat >&2 <<EOF
usage: `basename $0` [--version] [--noprompt] [--device <devicefile>]
       [--verbose -v] [--iso] [--kernelargs <args>] [--size <size>]  <kernel>
       (ex: `basename $0` --device /dev/fd1 2.0.31)
EOF
    exit $1
}

while [ $# -gt 0 ]; do
    case $1 in
        --device)
            shift
            device=$1
            ;;
        --kernelargs)
            shift
            kernelargs=$1
            ;;
        --help)
            rm -rf $MOUNTDIR
            usage 0
            ;;
        --iso)
            isoimage=1
            ;;
        --size)
            shift
            size=$1
            ;;
        --noprompt)
            unset pause
            ;;
        -v)
            verbose=true
            ;;
        --verbose)
            verbose=true
            ;;
        --version)
            echo "mkbootdisk: version $VERSION"
            rm -rf $MOUNTDIR
            exit 0
            ;;
        *)
            if [ -z "$kernel" ]; then
                kernel=$1
            else
                rm -rf $MOUNTDIR
                usage
            fi
            ;;
    esac

    shift
done

[ -z "$kernel" ] && {
    rm -rf $MOUNTDIR
    usage 1
}

[ -d /lib/modules/$kernel ] || {
    echo "/lib/modules/$kernel is not a directory." >&2
    rm -rf $MOUNTDIR
    exit 1
}

[ -f /boot/vmlinuz-$kernel ] || {
    echo "/boot/vmlinuz-$kernel does not exist." >&2
    rm -rf $MOUNTDIR
    exit 1
}


rootdev=`awk '$1 ~ /^[^#]/ && $2 ~ /^\/$/ { print $1 ; exit }' /etc/fstab`

if [ $(echo $rootdev | cut -c1-6) = "LABEL=" ]; then
    rootlabel=$(echo $rootdev | cut -c7-)

    # whee, now we have to look through every partition looking for
    # the thing called $rootlabel, which could be raid. Ick.

    list=$(tail +3 /proc/partitions | awk '{ print $4 '} | grep '^md')
    list="$list $(tail +3 /proc/partitions |
                        awk '{ print $4 '} | grep -v '^md')"
    rootdev=""
    for dev in $list; do
        if tune2fs -l /dev/$dev >/dev/null 2>/dev/null; then
            label=$(tune2fs -l /dev/$dev 2>/dev/null |
                grep "Filesystem volume name" | awk '{print $4}')
            if [ "$label" = $rootlabel ]; then
                rootdev=/dev/$dev
                break
            fi
        fi
    done
fi

if [ -z "$kernelargs" -a -x /sbin/grubby -a -f /boot/grub/grub.conf ]; then
    # sed gross... this grep's for the args= line and removes the args=" and "$
    defkernel=$(grubby --default-kernel)
    if [ -n "$defkernel" ]; then
        kernelargs=$(grubby --info "$defkernel" |
                     sed -n '/^args=/{s/^args="//;s/"$//;p;}')
    fi
fi

[ -z "$rootdev" ] && {
    echo 'Cannot find root partition in /etc/fstab.' >&2
    rm -rf $MOUNTDIR
    exit 1
}

rm -rf $MOUNTDIR
mkdir $MOUNTDIR || {
    echo "Failed to create $MOUNTDIR" >&2
    exit 1
}
[ -d $MOUNTDIR ] || {
    echo "$MOUNTDIR is not a directory!" >&2
    rm -rf $MOUNTDIR
    exit 1
}

if [ -n "$isoimage" ]; then
    cfgfile=$MOUNTDIR/isolinux/isolinux.cfg
    bootmsg=$MOUNTDIR/isolinux/boot.msg

    # create an iso image; the directory is all we need
    [ -n "$verbose" ] && echo -n "Installing isolinux... "
    mkdir $MOUNTDIR/isolinux
    cp /usr/lib/syslinux/isolinux.bin $MOUNTDIR/isolinux
    [ -n "$verbose" ] && echo done
else
    cfgfile=$MOUNTDIR/syslinux.cfg
    bootmsg=$MOUNTDIR/boot.msg

    # we need to create an msdos filesystem for syslinux

    if [ -b "$device" ]; then
        if [ -n "$pause" ]; then
            echo "Insert a disk in $device. Any information on the disk will be lost."
            echo -n "Press <Enter> to continue or ^C to abort: "
            read aline
        fi

        # this is copying some bits from below.  oh well
        realdev=$device
        device=`/bin/mktemp /tmp/mkbootdisk.XXXXXX`
        dd if=/dev/zero of=$device bs=1024 count=$size 2> /dev/null
        mountopts=loop
    elif [ -f "$device" ]; then
        echo "$device exists but is not a block device."
        rmdir $MOUNTDIR
        exit 1
    else
        dd if=/dev/zero of=$device bs=1024 count=$size 2> /dev/null
        mountopts=loop
    fi

    [ -n "$verbose" ] && echo -n "Formatting $device... "
    mkdosfs -r 16 -I $device > /dev/null || {
        echo "Failed to format $device" >&2
        rmdir $MOUNTDIR
        [ -n "$realdev" ] && rm -f "$device"
        exit 1
    }

    syslinux $device
    [ -n "$verbose" ] && echo "done."

    mount -o "$mountopts" -t vfat $device $MOUNTDIR || {
        rmdir $MOUNTDIR
        [ -n "$realdev" ] && rm -f "$device"
        exit 1
    }
fi


if [ -n "$isoimage" ]; then
    BOOTDESTDIR=$MOUNTDIR/isolinux
else
    BOOTDESTDIR=$MOUNTDIR
fi

[ -n "$verbose" ] && echo -n "Copying /boot/vmlinuz-$kernel... "
cp -p /boot/vmlinuz-$kernel $BOOTDESTDIR/vmlinuz
[ $? = 0 ] || failed=1
[ -n "$verbose" ] && echo "done."

[ -n "$verbose" ] && echo -n "Copying /boot/initrd-$kernel.img... "
if [ -f /boot/initrd-$kernel.img ]; then
  cp -p /boot/initrd-$kernel.img $BOOTDESTDIR/initrd.img
fi
[ $? = 0 ] || failed=1
[ -n "$verbose" ] && echo "done."

[ -n "$verbose" ] && echo -n "Configuring bootloader... "

[ -f $BOOTDESTDIR/initrd.img ] && INITRDARG="initrd=initrd.img"

if [ $(echo $rootdev | cut -b 6-9) = "loop" ]; then
    rootdev=$(ls -l $rootdev | sed 's/,//' | awk '{ printf("%02x%02x\n", $5, $6); }')
fi

cat > $cfgfile <<EOF
default linux
prompt 1
display boot.msg
timeout 100
label linux
        kernel vmlinuz
        append $INITRDARG $kernelargs root=$rootdev
EOF

[ $? = 0 ] || failed=1

chmod 644 $cfgfile

if [ -f /etc/redhat-release ]; then
    title="$(sed 's/ release.*$//' < /etc/redhat-release)"
else
    title="Red Hat Linux"
fi


cat >> $bootmsg <<EOF

Press <return> (or wait 10 seconds) to boot your $title system from
$rootdev. You may override the default linux kernel parameters by typing
"linux <params>", followed by <return> if you like.

EOF

[ $? = 0 ] || failed=1

[ -n "$verbose" ] && echo "done."

if [ -n "$isoimage" ]; then
    mkisofs \
        -A "Red Hat Linux Boot CD" \
        -V "Red Hat Linux Boot CD" \
        -J -R -T -quiet \
        -o $device \
        -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot \
           -boot-load-size 4 -boot-info-table $MOUNTDIR
    rm -rf $MOUNTDIR
else
    umount $MOUNTDIR
    rmdir $MOUNTDIR
fi

if [ -n "$realdev" ] && [ $failed -eq 0 ]; then
    dd if="$device" of="$realdev" bs=72k
    rm -f "$device"
fi

if [ $failed -eq 1 ]; then
  exit 1
else
  exit 0
fi


Comentario[s]

Sólo los usuarios registrados pueden escribir comentarios.
Por favor, valídate o regístrate.

Powered by AkoComment 2.0!

 
< Anterior   Siguiente >