home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / bin / mkbimage < prev    next >
Encoding:
Text File  |  2004-07-24  |  10.9 KB  |  418 lines

  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>
  5.  
  6.  
  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.
  11. #
  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.
  16. #
  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.
  21.  
  22. # $Id: mkbimage,v 1.19 2004/07/21 14:43:04 robertmh Exp $
  23.  
  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
  32.  
  33. # You can set GRUB_PATH  if you need to use a specially located GRUB.
  34. # This MUST end by a '/'!
  35.  
  36.  
  37. #----------------------------DON'T CHANGE: INTERNALS
  38.  
  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=
  58.  
  59. # Name by which this script was invoked.
  60. program=`echo "$0" | sed -e 's/[^\/]*\///g'`
  61. version_number='$Revision: 1.19 $'
  62.  
  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
  66.  
  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]
  81.  
  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]
  85.  -F
  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
  95.  
  96. Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>. 
  97. Copyright (c) 2001,2002 Robert Millan <zeratul2@wanadoo.es>.
  98. GPLed."
  99.  
  100. version="mkbimage $version_number
  101.  
  102. Written by Thierry Laronde and Robert Millan.
  103.  
  104. Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
  105. Copyright (c) 2001,2002,2003 Robert Millan <zeratul2@wanadoo.es>.
  106.  
  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."
  110.  
  111. # Functions
  112.  
  113. error ()
  114. {
  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
  139. }
  140.  
  141. # create a filesystem of type $fs in $image with offset $offset
  142. mkbimage_mkfs ()
  143. {
  144.   case $offset in
  145.     0)  lo_options="";;
  146.     *) lo_options="-o $offset";;
  147.   esac
  148.  
  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
  157.   fi
  158. }
  159.  
  160. # copy ${image}1/* to ${image}:/, assuming ${image} contains a filesystem
  161. # of type $fs in offset $offset
  162. mkbimage_cp ()
  163. {
  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";;
  175.     *)
  176.       cp="";
  177.       mkdir="";;
  178.   esac
  179.  
  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
  197.   fi
  198. }
  199.  
  200. #**********************************************************************
  201. #                          MAIN PROGRAM                               *
  202. #**********************************************************************
  203.  
  204. #---------------------- Getting the options
  205.  
  206. [ $# -eq 0 ] && error missing_option;
  207.  
  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;
  232.  
  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 ;
  240. fi
  241.  
  242. [ ! "$fs" ] && fs=ext2
  243.  
  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
  267.  
  268. # What type of tar file has been given ?
  269.  
  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
  278.  
  279. [ ! "$dir" ] && dir=`pwd`
  280.  
  281. image=$dir/$image_type.image
  282. device_map=$dir/device.map
  283.  
  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))
  287.  
  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))
  291.  
  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
  333.  
  334. type_option="-t $image_type"
  335.  
  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))
  340.  
  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.
  344.  
  345. if [ "$image_type" = "hd" ]; then
  346.   sfdisk -C $cylinders -H $heads -S $sectors -D $image<<EOT
  347. ,,$part_id,*,0,1,1
  348.  
  349.  
  350. EOT
  351.   offset="$(($sectors * $block_size))" 
  352.   type_option=
  353. else
  354.   offset="0"
  355. fi
  356.  
  357. # It's time now to create the filesystem on the first partition.
  358. mkbimage_mkfs
  359.  
  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 -
  364.  
  365. # copy the untarred files into the filesystem image
  366. mkbimage_cp
  367.  
  368. #We verify that the stage2 exists and we search the name
  369. stage2_os_name=`find ${image}1 -name stage2 -type f`
  370.  
  371. [ -r "$stage2_os_name" ] || { echo "I can't find stage2!"; exit 1;}
  372.  
  373. #------------------------- GRUB stuff
  374. if [ "$image_type" = "hd" ]; then
  375.     device='(hd0)'
  376.     root='(hd0,0)'
  377. else
  378.     device='(fd0)'
  379.     root='(fd0)'
  380. fi
  381.  
  382. cat<<EOT >$device_map
  383. $device    ${image}
  384. EOT
  385.  
  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
  391. EOT
  392.  
  393. echo "-------------------WHAT'S NEXT?-------------------------------------"
  394. echo
  395.  
  396. cat <<EOF
  397. If you have created an image aimed to a floppy, then something like:
  398.  
  399. dd if=<type>.image of=/dev/fd0[u<size>] bs=512
  400.  
  401. will be more than enough... if you have formated the floppy correctly
  402. using \`superformat' to be found in \`fdutils' package.
  403.  
  404. For El Torito floppy emulation :
  405.  
  406. mkisofs -b <image> -c boot.catalog -o raw.iso <dir>
  407.  
  408. And for El Torito Hard Disk emulation:
  409.  
  410. mkisofs -b <image> -hard-disk-boot -c boot.catalog -o raw.iso <dir> 
  411.  
  412. Enjoy!
  413. EOF
  414.  
  415. rm -rf ${image}1
  416.  
  417. exit 0
  418.