Merge branch 'master' of git://github.com/illumos/illumos-gate
[unleashed.git] / usr / src / grub / grub-0.97 / util / mkbimage
blob689f694abf72654f95afa6cdccaddf5d43150aca
1 #!/bin/sh
2 # MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode
3 # C) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>
4 # C) 2001,2002,2003 Robert Millan <robertmh@gnu.org>
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2, or (at your option)
10 # any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, you can either send email to this
19 # program's maintainer or write to: The Free Software Foundation,
20 # Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
22 # $Id: mkbimage,v 1.19 2004/07/21 14:43:04 robertmh Exp $
24 # Global variables
25 tarfile=
26 dir=
27 fs= #file system type
28 decompress=
29 image_type=
30 uname=`uname -s`
31 PATH=/sbin:$PATH
33 # You can set GRUB_PATH if you need to use a specially located GRUB.
34 # This MUST end by a '/'!
37 #----------------------------DON'T CHANGE: INTERNALS
39 block_size=512
40 cylinders=
41 heads=
42 sectors=
43 cyl_size=
44 type_option=
45 geo_option=
46 image=
47 bk_120=$((2 * 15 * 80))
48 bk_144=$((2 * 18 * 80))
49 bk_288=$((2 * 36 * 80))
50 bk_160=$((2 * 20 * 80))
51 bk_168=$((2 * 21 * 80))
52 bk_174=$((2 * 21 * 83))
53 lo_options=
54 device_map=
55 mkfs_options=
56 debug=
57 stage2_os_name=
59 # Name by which this script was invoked.
60 program=`echo "$0" | sed -e 's/[^\/]*\///g'`
61 version_number='$Revision: 1.19 $'
63 usage="
64 Usage: $program [-hVF] [-t TYPE] [-d DIRECTORY] [-s FS_TYPE] -f TAR_FILE
65 Make a Bootable IMAGE using GRUB as a bootloader
67 Options:
68 Actions:
69 -d DIRECTORY [default CWD]
70 Directory where the boot.image and the partition subdirectories
71 are/will be created
72 -f TAR_FILE
73 Name of the tar file containing the filesystem to install. Can
74 be a pure tar file [.tar] or a compressed tar file
75 [.tar.gz|.tar.bz2]
76 -s FS_TYPE
77 Type of the file system to create on the virtual disk. Choices
78 are:
79 ext2 on GNU [default is ext2]
80 ext2, minix or msdos on GNU/Linux [default is ext2]
82 -t TYPE
83 Type of the image to create. Choices are '1.20', '1.44', '1.60',
84 '1.68', '1.74', '2.88' or 'hd' [default is hd]
86 Force to set the set_dpt flag (unnecessary 99% of the time! Be
87 careful!
88 Informations:
89 -D
90 turn Debugging on [xtrace]
91 -h|--help
92 display this Help and exit
93 -V|--version
94 display Version information and exit
96 Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
97 Copyright (c) 2001,2002 Robert Millan <zeratul2@wanadoo.es>.
98 GPLed."
100 version="mkbimage $version_number
102 Written by Thierry Laronde and Robert Millan.
104 Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
105 Copyright (c) 2001,2002,2003 Robert Millan <zeratul2@wanadoo.es>.
107 This is free software under the GPL version 2 or later; see the source for
108 copying conditions. There is NO warranty, not even for MERCHANTABILITY or
109 FITNESS FOR A PARTICULAR PURPOSE."
111 # Functions
113 error ()
115 case $1 in
116 bug) echo "This is a bug!";
117 echo "$usage";;
118 option) echo "Unknow option"; echo "$usage";;
119 missing_argument) echo "You must give an argument to the option!";
120 echo "$usage";;
121 missing_option) echo "You must indicate at least one option!";
122 echo "$usage";;
123 must_be_root) echo "You must be root! (or install e2tools/mtools)";;
124 unknown_fs) if [ $uname = Linux ];
125 then echo "The GNU/Linux supported fs are: ext2, minix or msdos!";
126 elif [ $uname = GNU ];
127 then echo "The GNU supported fs is ext2!";
128 fi;;
129 unknown_format) echo "The tar file must be .tar|.tar.gz|.tar.bz2!";;
130 wont_fit) echo "The files won't fit on the selected type of media!";;
131 wrong_directory) echo "Directory inexistant or not given!";
132 echo "$usage";;
133 wrong_file) echo "File inexistant or empty!";
134 echo "$usage";;
135 wrong_type) echo "The type specified is not a valid one!";
136 echo "$usage";;
137 esac
138 exit 1
141 # create a filesystem of type $fs in $image with offset $offset
142 mkbimage_mkfs ()
144 case $offset in
145 0) lo_options="";;
146 *) lo_options="-o $offset";;
147 esac
149 if [ "$offset" = "0" ] ; then
150 mkfs.$fs -F $image
151 elif [ `id -u` = "0" ] ; then
152 losetup $lo_options /dev/loop1 $image
153 mkfs.$fs /dev/loop1
154 losetup -d /dev/loop1
155 else
156 error must_be_root
160 # copy ${image}1/* to ${image}:/, assuming ${image} contains a filesystem
161 # of type $fs in offset $offset
162 mkbimage_cp ()
164 case $offset in
165 0) lo_options="";;
166 *) lo_options="-o $offset";;
167 esac
168 case $fs in
169 ext2)
170 cp="e2cp";
171 mkdir="e2mkdir";;
172 vfat)
173 cp="mcopy";
174 mkdir="mmd";;
176 cp="";
177 mkdir="";;
178 esac
180 if [ "$offset" = 0 ] && which $cp > /dev/null ; then
181 for dir in $(cd ${image}1 && find -type d) ; do
182 $mkdir ${image}:$dir
183 done
184 for file in $(cd ${image}1 && find -type f) ; do
185 $cp ${image}1/$file ${image}:$file
186 done
187 elif [ "`id -u`" = "0" ] ; then
188 losetup $lo_options /dev/loop1 $image
189 mkdir ${image}.mnt
190 mount -t $fs /dev/loop1 ${image}.mnt
191 cp -a ${image}1/* ${image}.mnt/ && sync
192 umount ${image}.mnt
193 rmdir ${image}.mnt
194 losetup -d /dev/loop1
195 else
196 error must_be_root
200 #**********************************************************************
201 # MAIN PROGRAM *
202 #**********************************************************************
204 #---------------------- Getting the options
206 [ $# -eq 0 ] && error missing_option;
208 while [ $# -gt 0 ]; do
209 case "$1" in
210 -d) shift;
211 dir="$1";
212 [ ! -d "$1" ] && error wrong_directory;;
213 -f) shift;
214 tarfile="$1";
215 [ -z "$tarfile" ] && error missing_argument;;
216 -s) shift;
217 fs="$1";;
218 -t) shift;
219 image_type="$1";;
220 -F) geo_option="-F";;
221 -D) debug="-v";
222 set -x;;
223 -h|--help) echo "$usage"; exit 0;;
224 -V|--version) echo "$version"; exit 0;;
225 *) error option ;;
226 esac
227 shift
228 done
229 #---------------------- Sanity checks
230 [ ! "$tarfile" ] && error missing_argument;
231 [ ! -s "$tarfile" ] && error wrong_file;
233 if [ ! "$image_type" ]; then
234 image_type=hd;
235 elif [ "$image_type" != "1.20" ] && [ "$image_type" != "1.44" ] \
236 && [ "$image_type" != "1.60" ] && [ "$image_type" != "1.68" ] \
237 && [ "$image_type" != "2.88" ] && [ "$image_type" != "1.74" ] \
238 && [ "$image_type" != "hd" ] && [ "$image_type" != "1.60" ] ; then
239 error wrong_type ;
242 [ ! "$fs" ] && fs=ext2
244 # Carlo Contavalli reported that I [TL] have forgotten to specify the
245 # partition ID for sfdisk to correctly fill the partition table (ext2 is the
246 # default on Linux, so this worked in this case...). This is fixed below.
247 case "$fs" in
248 ext2) mkfs_options="-m 0";
249 part_id="83";; # This is the default
250 # ufs) if [ $uname = Linux ];
251 # then error unknown_fs;
252 # fi;;
253 minix) if [ $uname = GNU ];
254 then error unknown_fs;
255 else
256 mkfs_options="-v"; # Minix version 2
257 part_id="81";
258 fi;;
259 msdos) if [ $uname = GNU ];
260 then error unknown_fs;
261 else
262 mkfs_options="-f 1 -F 12"; # the smallest...
263 part_id="1";
264 fi;;
265 *) error unknown_fs;;
266 esac
268 # What type of tar file has been given ?
270 suffix=`echo "$tarfile" | sed -n 's/^.*\.\([targbz2]\{2,3\}\)$/\1/p'`
271 case "$suffix" in
272 tar) decompress="cat";;
273 gz) decompress="gunzip -c";;
274 bz2) decompress="bunzip2 -c";;
275 *) error unknown_format;;
276 esac
277 #---------------------- Initializations
279 [ ! "$dir" ] && dir=`pwd`
281 image=$dir/$image_type.image
282 device_map=$dir/device.map
284 # First, find the size of the tar file in block_size.
285 file_size=`$decompress $tarfile | wc -c | tr -d ' '`
286 file_size=$(($file_size / $block_size + 1))
288 # Increase in order to be sure that with a fs there will be enough
289 # room (trying 110%)
290 file_size=$(($file_size + $file_size / 10))
292 case "$image_type" in
293 hd) heads=16;
294 sectors=63;
295 cyl_size=$((16 * 63));
296 # Create the minimum number of cylinders. At the moment, we leave
297 # some space by rounding everything up by adding 1 cylinder, plus
298 # another one for MBR + reserved track.
299 cylinders=$(($file_size / $cyl_size + 2));;
300 1.20) [ $file_size -ge $bk_120 ] && error wont_fit;
301 heads=2;
302 sectors=15;
303 cyl_size=$((2 * 15));
304 cylinders=80;;
305 1.44) [ $file_size -ge $bk_144 ] && error wont_fit;
306 heads=2;
307 sectors=18;
308 cyl_size=$((2 * 18));
309 cylinders=80;;
310 1.60) [ $file_size -ge $bk_160 ] && error wont_fit;
311 heads=2;
312 sectors=20;
313 cyl_size=$((2 * 20));
314 cylinders=80;
315 geo_option="-F";;
316 1.68) [ $file_size -ge $bk_168 ] && error wont_fit;
317 heads=2;
318 sectors=21;
319 cyl_size=$((2 * 21));
320 cylinders=80;;
321 1.74) [ $file_size -ge $bk_174 ] && error wont_fit;
322 heads=2;
323 sectors=21;
324 cyl_size=$((2 * 21));
325 cylinders=83;;
326 2.88) [ $file_size -ge $bk_288 ] && error wont_fit;
327 heads=2;
328 sectors=36;
329 cyl_size=$((2 * 36));
330 cylinders=80;;
331 *) error bug;;
332 esac
334 type_option="-t $image_type"
336 # We start by creating a virtual disk which size is the number of
337 # cylinders of $cyl_size mandatory to put the files stocked in the $tarfile
338 # Create the empty virtual disk
339 dd if=/dev/zero of=$image bs=$block_size count=$(($cyl_size * $cylinders))
341 # We then format the virtual disk
342 # NOTE: the El Torito specification wants only one partition. So we
343 # create the first, and the remaining 3 entries are empty.
345 if [ "$image_type" = "hd" ]; then
346 sfdisk -C $cylinders -H $heads -S $sectors -D $image<<EOT
347 ,,$part_id,*,0,1,1
351 offset="$(($sectors * $block_size))"
352 type_option=
353 else
354 offset="0"
357 # It's time now to create the filesystem on the first partition.
358 mkbimage_mkfs
360 # then untar the files
361 [ ! -e ${image}1 ] || { echo "${image}1 exists, please remove it first"; exit 1;}
362 mkdir -p ${image}1
363 $decompress $tarfile | tar -C ${image}1 $debug -xf -
365 # copy the untarred files into the filesystem image
366 mkbimage_cp
368 #We verify that the stage2 exists and we search the name
369 stage2_os_name=`find ${image}1 -name stage2 -type f`
371 [ -r "$stage2_os_name" ] || { echo "I can't find stage2!"; exit 1;}
373 #------------------------- GRUB stuff
374 if [ "$image_type" = "hd" ]; then
375 device='(hd0)'
376 root='(hd0,0)'
377 else
378 device='(fd0)'
379 root='(fd0)'
382 cat<<EOT >$device_map
383 $device ${image}
386 ${GRUB_PATH}grub --device-map=$device_map --batch<<EOT
387 geometry $device $cylinders $heads $sectors
388 root $root
389 setup $device
390 geometry $geo_option -w $type_option $device $cylinders $heads $sectors
393 echo "-------------------WHAT'S NEXT?-------------------------------------"
394 echo
396 cat <<EOF
397 If you have created an image aimed to a floppy, then something like:
399 dd if=<type>.image of=/dev/fd0[u<size>] bs=512
401 will be more than enough... if you have formated the floppy correctly
402 using \`superformat' to be found in \`fdutils' package.
404 For El Torito floppy emulation :
406 mkisofs -b <image> -c boot.catalog -o raw.iso <dir>
408 And for El Torito Hard Disk emulation:
410 mkisofs -b <image> -hard-disk-boot -c boot.catalog -o raw.iso <dir>
412 Enjoy!
415 rm -rf ${image}1
417 exit 0