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

GRUB, CD and extended floppy formats: HOWTO



Hello,

The patches have been sent to the GRUB mailing list.

To use the new features, I have attached a script (to be run under Linux
since it uses loosetup) to create virtual bootable disks.

The name of the script is `mkbimage', Make a Bootable IMAGE using GRUB
as a bootloader.

Usage: mkbimage [-h] [-V] [-t TYPE] [-d DIRECTORY] [-s FS_TYPE] -f
TAR_FILE

type:

mkbimage -h 

to display the help. It should be self-explanatory!

In brief.

You create a tar archive with all the files that you want to put on the
virtual disk INCLUDING the ones for the correct version of GRUB. All the
remaining stuff is handled by the script which creates an empty file of
the correct size, partitions it (in case of HD emulation), put a
filesystem on it (only ext2 at the moment, but this is just a limitation
of the script), run GRUB with the correct options, that is uses `setup'
and the `geometry' function with new options to set the correct geometry.

Once this is done, you have a virtual bootable disk, that can be used on
floppies (1.20, 1.44, 2.88, 1.68, 1.74) or as a HD for El Torito
emulation.

The script displays at the end a remainder of the command to use with
mkisofs.

You than have all the features of GRUB (chaining different menu files,
loading different kernels and so on, network boot etc.).

Enjoy! [and test...]
-- 
Thierry Laronde <tlaronde@polynum.org>
Site Debian Francophone (aka SDF) : http://www.debian-france.org/
#!/bin/sh
# MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode
# C) 2001 Thierry Laronde <tlaronde@polynum.org>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, you can either send email to this
# program's maintainer or write to: The Free Software Foundation,
# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.

# $Id: mkbimage,v 1.2 2001/10/14 15:19:55 tlaronde Exp $

# Global variables
tarfile=
dir=
fs= #file system type
decompress=
image_type=

#----------------------------DON'T CHANGE: INTERNALS
block_size=512
cylinders=
heads=
sectors=
cyl_size=
type_option=
geo_option=
image=
bk_120=$((2 * 15 * 80))
bk_144=$((2 * 18 * 80))
bk_288=$((2 * 36 * 80))
bk_160=$((2 * 20 * 80))
bk_168=$((2 * 21 * 80))
bk_174=$((2 * 21 * 83))
lo_options=
device_map=

# Name by which this script was invoked.
program=`echo "$0" | sed -e 's/[^\/]*\///g'`
mkbimage_version='$Id: mkbimage,v 1.2 2001/10/14 15:19:55 tlaronde Exp $'

usage="
Usage: $program [-h] [-V] [-t TYPE] [-d DIRECTORY] [-s FS_TYPE] -f TAR_FILE
Make a Bootable IMAGE using GRUB as a bootloader

Options:
 Actions:
 -d DIRECTORY [default CWD]
 	Directory where the boot.image and the partition subdirectories
	are/will be created
 -f TAR_FILE
 	Name of the tar file containing the filesystem to install. Can
	be a pure tar file [.tar] or a compressed tar file
	[.tar.gz|.tar.bz2]
 -s FS_TYPE
 	Type of the file system to create on the virtual disk [default
	is ext2]. XXX: At the moment the script has been designed for ext2.
 -t TYPE
 	Type of the image to create. Choices are '1.20', '1.44', '1.68', '1.74'
	'2.88' or 'hd' [default is hd]
 Informations:
 -h	display this Help and exit
 -V	display Version information and exit

Copyright (c) 2001 Thierry Laronde <tlaronde@polynum.org>. GPLed."

version="$mkbimage_version
Written by Thierry Laronde.

Copyright (c) 2001 Thierry Laronde <tlaronde@polynum.org>.
This is free software under the GPL version 2 or later; see the source for 
copying conditions.  There is NO warranty, not even for MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE."

# Functions

error ()
{
	case $1 in
	bug) echo "This is a bug!";
		echo "$usage";;
	option) echo "Unknow option"; echo "$usage";;
	missing_argument) echo "You must give an argument to the option!";
		echo "$usage";;
	missing_option) echo "You must indicate at least one option!";
		echo "$usage";;
	must_be_root) echo "You must be root!";;
	unknown_format) echo "The tar file must be .tar|.tar.gz|.tar.bz2 !";;
	wont_fit) echo "The files won't fit on the selected type of media!";;
	wrong_directory) echo "Directory inexistant or not given!";
		echo "$usage";;
	wrong_file) echo "File inexistant or empty!";
		echo "$usage";;
	wrong_type) echo "The type specified is not a valid one!";
		echo "$usage";;
	esac	
	exit 1
}

#**********************************************************************
#                          MAIN PROGRAM                               *
#**********************************************************************

#---------------------- Getting the options

[ $# -eq 0 ] && error missing_option;

while [ $# -gt 0 ]; do
	case "$1" in
		-d) shift;
			dir="$1";
			[ ! -d "$1" ] && error wrong_directory;;
		-f) shift;
			tarfile="$1";
			[ -z "$tarfile" ] && error missing_argument;;
		-s) shift;
			fs="$1";;
		-t) shift;
			image_type="$1";;
		-h) echo "$usage"; exit 0;;
		-V) echo "$version"; exit 0;;
	 	*) error option ;;
	esac
shift	
done
#---------------------- Must be root
[ ! `id -u` -eq 0 ] && error must_be_root;

[ ! "$tarfile" ] && error missing_argument;
[ ! -s "$tarfile" ] && error wrong_file;

if [ ! "$image_type" ]; then
	image_type=hd;
elif [ "$image_type" != "1.20" -a "$image_type" != "1.44" \
  -a "$image_type" != "1.68" \
  -a "$image_type" != "2.88" -a "$image_type" != "1.74" \
  -a "$image_type" != "hd" -a "$image_type" != "1.60" ] ; then
  error wrong_type ;
fi

#---------------------- Initializations

[ ! "$dir" ] && dir=`pwd`
[ ! "$fs" ] && fs=ext2

# What type of tar file has been given ?

suffix=`echo "$tarfile" | sed -n 's/^.*\.\([targbz2]\{2,3\}\)$/\1/p'`
case "$suffix" in
	tar) decompress="cat";;
	gz) decompress="gunzip -c";;
	bz2) decompress="bunzip2 -c";;
	*) error unknown_format;;
esac

image=$dir/$image_type.image
device_map=$dir/device.map

# First, find the size of the tar file in block_size.
file_size=`$decompress $tarfile | wc -c | tr -d ' '`
file_size=$(($file_size / $block_size + 1))

case "$image_type" in
  hd) heads=16;
    sectors=63;
    cyl_size=$((16 * 63));
    # One cylinder for MBR and  one to round up
    cylinders=$(($file_size / $cyl_size + 2));; 
  1.20) [ $file_size -ge $bk_120 ] && error wont_fit; 
    heads=2;
    sectors=15;
    cyl_size=$((2 * 15));
    cylinders=80;;
  1.44) [ $file_size -ge $bk_144 ] && error wont_fit; 
    heads=2;
    sectors=18;
    cyl_size=$((2 * 18));
    cylinders=80;;
  1.60) [ $file_size -ge $bk_160 ] && error wont_fit; 
    heads=2;
    sectors=20;
    cyl_size=$((2 * 20));
    cylinders=80;
    geo_option="-F";;
  1.68) [ $file_size -ge $bk_168 ] && error wont_fit; 
    heads=2;
    sectors=21;
    cyl_size=$((2 * 21));
    cylinders=80;;
  1.74) [ $file_size -ge $bk_174 ] && error wont_fit; 
    heads=2;
    sectors=21;
    cyl_size=$((2 * 21));
    cylinders=83;;
  2.88) [ $file_size -ge $bk_288 ] && error wont_fit;
    heads=2;
    sectors=36;
    cyl_size=$((2 * 36));
    cylinders=80;;
  *) error bug;;
esac

type_option="-t $image_type"

[ "$image_type" = "1.60" ] && type_option=
# We start by creating a virtual disk which size is the number of
# cylinders of $cyl_size mandatory to put the files stocked in the $tarfile

# We then create the empty virtual disk
dd if=/dev/zero of=$image bs=$block_size count=$(($cyl_size * $cylinders))

# We then format the virtual disk
# NOTE: the El Torito specification wants only one partition. So we
# create the first, and the remaining 3 entries are empty.


if [ "$image_type" = "hd" ]; then
sfdisk -C $cylinders -H $heads -S $sectors -D $image<<EOT
,,,*,0,1,1


EOT
lo_options="-o $(($sectors * $block_size))" 
type_option=
fi

losetup /dev/loop0 $image

# It's time now to create the filesystem on the first partition.
# Hence, we mount via the loop device the part of the virtual disk
# dedicated to the first partition. We must, indeed, skip one cylinder
# if this is a hard disk image

losetup $lo_options /dev/loop1 $image

mkfs.$fs -m 0 /dev/loop1

# We then create the mount point for the first partition
mkdir  ${image}1 2>/dev/null

# and mount the partition
mount -t $fs /dev/loop1 ${image}1

# then untar the files
$decompress $tarfile | tar -C ${image}1 -xf -


# Find stage2 name
stage2=
while [ ! "$stage2" ]; do
stage2=`find ${image}1 -type f -name stage2 2>/dev/null`
done

sync
umount ${image}1
losetup -d /dev/loop1
losetup -d /dev/loop0
losetup /dev/loop0 $image

#------------------------- GRUB stuff
if [ "$image_type" = "hd" ]; then
	device='(hd0)'
	root='(hd0,0)'
else
	device='(fd0)'
	root='(fd0)'
fi

cat<<EOT >$device_map
$device	/dev/loop0
EOT

# setup --stage2=$stage2 --force-lba $device

grub --device-map=$device_map --batch<<EOT
geometry $device $cylinders $heads $sectors
root $root
setup $device
geometry $geo_option -w $type_option $device $cylinders $heads $sectors
EOT
# Freing everything
losetup -d /dev/loop0

echo "-------------------WHAT'S NEXT--------------------"
echo
echo

cat <<EOF
If you have created an image aimed to a floppy, then something like:
dd if=<type>.image of=/dev/fd0[u<size>] bs=512

will be more than enough.

For El Torito floppy emulation :

mkisofs -b <image> -c boot.catalog -o raw.iso DIR 

And for El Torito Hard Disk emulation:

mkisofs -b <image> -hard-disk-boot -c boot.catalog -o raw.iso DIR 

Enjoy!
EOF

exit 0

Reply to: