#! /bin/bash # by Andrew Clausen # Copyright (C) 2003 Silicon Graphics, Inc. # # This program is free software. It may be modified and/or distributed # under the terms of the GNU General Public Licence version 2 or later, # as published by the Free Software Foundation, Inc. There is NO WARRANTY. # # # "All problems in software engineering can be solved by adding another # layer of indirection" # -- folklore (?) # # This file can be found at http://members.optusnet.com.au/clausen/sgi # # This shell script makes ip22 and ip27 bootable CDs. It modifies # prepared Debian install CDs. Note that you must create a big empty file # (for ip27) on the CD image. # # # In the ip22 case (untested): the "internal" (-i) option should be used. # This creates an entry in the volume header for a particular file on the ISO. # # In the ip27 case: the "external" (-e) option should be used. This copies # an external file onto an XFS image which is stored in the "empty" file. # The empty file is mapped onto a partition, which the PROM can read from. # The motivation for this mess is: # (1) the PROM can't read from the volume header. (The ip27 PROM # is broken) It must therefore read from an xfs partition. # (2) Linux doesn't support partition tables on CDs. # To satisfy both Linux and the PROM, Linux must believe there is no # partition table, and the PROM must believe there is one. This is all # complicated by partition table requirements for cylinder alignment and # such. Hence the smoke and mirrors. Here's some ASCII art describing the # ip27 situation: # # +---------------------------------------------------------------+ # | +-----------+ +---------------------------+ | # | | Volume | | "empty file" | | # | | Header | ISO image | +-----------------+ | | # | | | | | XFS partition | | | # | | +-------+ | | | +------------+ | | | # | | | linux ======POINTS==================>linux kernel| | | | # | | +-------+ | | | +------------+ | | | # | +-----------+ | +-----------------+ | | # | +---------------------------+ | # +---------------------------------------+-----------------------+ # | # ^ cylinder boundary # # # You probably want to build CDs like this: # # mkdir iso_mnt # mkdir cd_contents # mount -o loop debian-mips-cd1.iso iso_mnt # (cd iso_mnt; tar c .) | (cd cd_contents; tar x) # dd if=/dev/zero of=cd_contents/bootdata bs=20M count=1 # cp indy-kernel-if-you-want.img iso_mnt/indy-linux # umount iso_mnt # # mkisofs -o iso.img -R cd_contents/ # # ./gen-mips-cd iso.img bootdata -e vmlinux.64 linux -i linux indy-linux fail() { umount xfs_mnt umount iso_mnt exit 1 } error() { echo $1 fail } warn() { echo "warning: $1" } usage() { cat << EOF use: gen-mips-cd iso empty-file [-i name:path]... [-e path:path]... iso the official Debian MIPS CD1 ISO image to be boot-ified. It need not be mounted (gen-mips-cd will mount it) empty-file the path of the big empty file inside the iso that can be overwritten [-i name path] add an internal boot file: this file should already exist on the iso, and will be added to the volume header. The path should be relative to the root of the iso-in root. [-e dst-path src-path] add an external boot file. It will be stored in an xfs partition on the CD that is stored in empty-file... so there must be room! EOF fail } if [ $# -lt 2 ]; then usage fi echo "gen-mips-cd, by Andrew Clausen " echo "Copyright (C) 2003 Silicon Graphics" ISO=$1 EMPTY_FILE=$2 shift 2 BLOCK_SIZE=2048 CYL_BLOCKS=8 [ ! -e iso_mnt ] && mkdir iso_mnt [ ! -e xfs_mnt ] && mkdir xfs_mnt echo mounting iso... echo mount $ISO iso_mnt -o loop || fail mount $ISO iso_mnt -o loop || fail [ -e iso_mnt/$EMPTY_FILE ] || error "$EMPTY_FILE doesn't exist" BLOCK_RANGE=$(./fblocks iso_mnt/$EMPTY_FILE $BLOCK_SIZE | tail -1) BLOCK_START=$(echo $BLOCK_RANGE | sed s/+.*//) BLOCK_LEN=$(echo $BLOCK_RANGE | sed s/.*+//) SAFE_LEN=$[$BLOCK_LEN - 2 * $CYL_BLOCKS] echo creating xfs image... [ -e xfs_image ] && rm xfs_image dd if=/dev/zero of=xfs_image bs=$BLOCK_SIZE count=$SAFE_LEN || fail /sbin/mkfs.xfs xfs_image || fail echo mounting xfs image... mount -o loop xfs_image xfs_mnt || fail while [ $# -gt 0 ]; do case $1 in -i) echo internal $2 $3 F_BLOCK_RANGE=$(./fblocks iso_mnt/$3 $BLOCK_SIZE \ | tail -1) F_BLOCK_START=$(echo $F_BLOCK_RANGE | sed s/+.*//) F_BLOCK_LEN=$(echo $F_BLOCK_RANGE | sed s/.*+//) F_START=$[$BLOCK_START * $BLOCK_SIZE] F_LEN=$[$BLOCK_LEN * $BLOCK_SIZE] GENISOVH_CMD="$GENISOVH_CMD $2:$F_START,$F_LEN" shift 3;; -e) echo adding $3 to xfs_mnt/$2 cp $3 xfs_mnt/$2 || fail shift 3;; *) echo "invalid option '$1'"; usage;; esac done umount xfs_mnt umount iso_mnt echo ./genisovh $ISO $GENISOVH_CMD \ 4:$[$BLOCK_START * $BLOCK_SIZE],$[$BLOCK_LEN * $BLOCK_SIZE],xfs_image ./genisovh $ISO $GENISOVH_CMD \ 4:$[$BLOCK_START * $BLOCK_SIZE],$[$BLOCK_LEN * $BLOCK_SIZE],xfs_image