Difference between revisions of "Mac Build Scripts"
(→Replicate Mac Ubuntu Disk: Host to Disk: more comment mods) |
(→genMacDisk.sh: leading comment mod) |
||
| Line 561: | Line 561: | ||
==genMacDisk.sh== | ==genMacDisk.sh== | ||
| − | + | This should be the current working version, if I have been diligent with updates. The'''yaboot.conf''' and '''fstab''' modifiers have been added. | |
| Line 928: | Line 928: | ||
fi | fi | ||
exit 0 | exit 0 | ||
| − | |||
==shrink_initrd.sh== | ==shrink_initrd.sh== | ||
Revision as of 23:18, 19 November 2007
Generate fdisk script
This script takes a raw device argument like /dev/hda and writes out a set of commands that can be fed to fdisk to automatically define a partition table for a Mac. The commands are written to a file named fdisk.script, but that can be changed to stdout, if this script needs to called from another script, for example. It is currently only tested for G3 towers, and needs more work and testing
#!/bin/sh
#
# create a set of input commands for fdisk to use to partition a blank
# drive for Macintosh machines.
#
# Partitions are created in the same order that an Ubuntu installation creates
# them:
# 1. partition map
# 2. boot partition
# 3. linux partition
# 4. swap partition
# The partition map is automatically created with length 63. The boot
# partition start block (64) and size (1954) are known (from the Ubuntu model).
# The swap partition size is fixed arbitrary size, chosen to support 512Mb
# of ram and to allow the swap and linux partition lengths to be even.
scriptName="fdisk.script"
genScript () {
# generate and write the commands, creating the script file
#
local target scriptName
# initialize partition table, answer disk length query, and show the result
echo i > $scriptName
echo "" >> $scriptName
echo p >> $scriptName
# create a boot partition with explicit partition size/type, and show result
echo C >> $scriptName
echo $bootstart >> $scriptName
echo $bootlen >> $scriptName
echo untitled >> $scriptName
echo Apple_Bootstrap >> $scriptName
echo p >> $scriptName
# create a linux native partition, and show result
echo c >> $scriptName
echo $linuxstart >> $scriptName
echo $linuxlen >> $scriptName
echo c >> $scriptName
echo p >> $scriptName
# create the swap partition. and show result
echo $swapstart >> $scriptName
echo $swaplen >> $scriptName
echo swap >> $scriptName
echo p >> $scriptName
# write out the partition map and confirm
echo w >> $scriptName
echo "" >> $scriptName
# we done partishin' now
echo q >> $scriptName
}
# first of all, best be root to do this
if [ $(whoami) != 'root' ]; then
echo "You must be root to run this script; try using sudo"
exit 1
fi
# need one argument
# target device
if [ -z $1 ]; then
echo "no target specified"
exit 2
else
target=$1
fi
# target device has to exist
hdparm -g $target > /dev/null 2>&1
status=$?
if [ $status -ne 0 ]; then
echo "device $target does not seem to exist"
exit 3
fi
# target device must have no partitions
n_partitions=$(( $(fdisk -l $target | grep $target | wc -l) ))
if [ $n_partitions -ne 0 ]; then
echo "There appear to be existing partitions on $target"
echo "Quitting"
exit 4
fi
# length of target drive
## get the hd geometry (hdparm), from that get (awk) the line that has
## "sectors" in it, and spit out the number of sectors from that line
## (sixth field); then remove (cut) the ',' from the end of the number;
## The hd length used for partition length calculations is actually one
## less that the true disk length, since block zero is ignored.
hdlen=$(hdparm -g $target | awk '/sector/ {print $6}' | cut -d ',' -f 1)
hdlen=$(($hdlen - 1))
# starts and lengths for boot, linux and swap partitions
#
# known values
mapstart=1
maplen=63
bootlen=1954
swaplen=1494848
#calculated values
bootstart=$(($mapstart + $maplen))
linuxstart=$(($bootstart + $bootlen))
linuxlen=$(($hdlen-($maplen + $bootlen + $swaplen)))
swapstart=$(($linuxstart+$linuxlen))
# debug
#echo "target= $target"
#echo "hdlen= $hdlen"
#echo "bootstart= $bootstart"
#echo "bootlen= $bootlen"
#echo "linuxstart= $linuxstart"
#echo "linuxlen= $linuxlen"
#echo "swapstart= $swapstart"
#echo "swaplen= $swaplen"
#calclen=$((63+$bootlen+$linuxlen+$swaplen))
#echo "calculated hdlen= $calclen"
genScript
exit 0
Replicate Mac Ubuntu Disk: Host to Disk
This script uses a bootpartition image and a copy of the root filesystem, both resident on the host in directory /root, to clone a Mac Ubuntu hard drive. Still needs boot partition mods for correct UUIDs (ybin or mkofboot), and fstab replacement. (The current working version is #genMacDisk.sh)
#!/bin/sh
#
# usage:
# copyMacDisk [-t macType] source-device target-device
# -t macType tweak the relevant files for the target environment
#
# Replicate a Mac Ubuntu disk onto a 'clean' disk; this script assumes
# that the source is a fully installed disk device in its own right and not
# the host on which this script is running. The target device is expected
# to be a 'clean' disk with no partition map.
# [There is an alternate implentation in my mind's eye that has the
# entire rooted file system, or install image, in a directory or partition
# of it's own on the host machine - tr]
#
# 1. Take two arguments, a source device and a target device, and possibly
# an option specifying the target platform
# 2. Verify that the source device has a Mac Ubuntu installation
# 3. Verify that the target device is a 'clean' disk
# 4. Create partitions on the target device
# 5. Create an ext3 filesystem on the linux partition of the target device
# 6. Use dd to copy the source boot partition to the target boot partition
# [There is an alternative: use 'mkofboot' to create an populate the
# target boot partition. In that case this step woujldn't happen until
# until after fstab and yaboot.conf are modified.]
# 7. Use rsync to copy the source linux image to the target linux partition
# 8. modify fstab and yaboot.conf files for target machine environment
# [see step 6]
errExit () {
# expect an error number and message string
# show the message, exit with the error number as exit status
local errno msg
errno=$1
msg=$2
echo $msg
exit $errno
}
genScript () {
# expect a filename string as an argument;
# create an fdisk script file with the argument filename, overwriting
# existing file of same name
local scriptName
scriptName=$1
# length of target drive
## get the hd geometry (hdparm), from that get (awk) the line that has
## "sectors" in it, and spit out the number of sectors from that line
## (sixth field); then remove (cut) the ',' from the end of the number;
## The hd length used for partition length calculations is actually one
## less that the true disk length, since block zero is ignored.
hdlen=$(hdparm -g /dev/$target | awk '/sector/ {print $6}' | cut -d ',' -f 1)
hdlen=$(($hdlen - 1))
# starts and lengths for boot, linux and swap partitions
#
# known values
mapstart=1
maplen=63
bootlen=1954
swaplen=1494848
#calculated values
bootstart=$(($mapstart + $maplen))
linuxstart=$(($bootstart + $bootlen))
linuxlen=$(($hdlen-($maplen + $bootlen + $swaplen)))
swapstart=$(($linuxstart+$linuxlen))
# generate and write the commands, creating the script file
#
# initialize partition table, answer disk length query, and show the result
echo i > $scriptName
echo "" >> $scriptName
echo p >> $scriptName
# create a boot partition with explicit partition size/type, and show result
echo C >> $scriptName
echo $bootstart >> $scriptName
echo $bootlen >> $scriptName
echo untitled >> $scriptName
echo Apple_Bootstrap >> $scriptName
echo p >> $scriptName
# create a linux native partition, and show result
echo c >> $scriptName
echo $linuxstart >> $scriptName
echo $linuxlen >> $scriptName
echo untitled >> $scriptName
echo p >> $scriptName
# create the swap partition. and show result
echo c >> $scriptName
echo $swapstart >> $scriptName
echo $swaplen >> $scriptName
echo swap >> $scriptName
echo p >> $scriptName
# write out the partition map and confirm
echo w >> $scriptName
echo yes >> $scriptName
# we done partishin' now
echo q >> $scriptName
}
genYbConf () {
# expect a boot-device string formatted as an OF device-tree name;
# write a candidate yaboot.conf file using target platform values for boot device,
# boot partition and linux root partition.
local bootdev
bootdev=$1
echo '## yaboot.conf generated by the Ubuntu installer' > $ybconfName
echo '##' >> $ybconfName
echo '## run: "man yaboot.conf" for details. Do not make changes until you have!!' >> $ybconfName
echo '## see also: /usr/share/doc/yaboot/examples for example configurations.' >> $ybconfName
echo '##' >> $ybconfName
echo '## For a dual-boot menu, add one or more of:' >> $ybconfName
echo '## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ' >> $ybconfName
echo >> $ybconfName
echo "boot=${actualbootpart}" >> $ybconfName
echo "device=${bootdev}" >> $ybconfName
echo 'partition=3' >> $ybconfName
echo "root=${actuallinuxpart}" >> $ybconfName
echo 'timeout=50' >> $ybconfName
echo 'install=/usr/lib/yaboot/yaboot' >> $ybconfName
echo 'magicboot=/usr/lib/yaboot/ofboot' >> $ybconfName
echo 'enablecdboot' >> $ybconfName
echo >> $ybconfName
echo 'image=/boot/vmlinux' >> $ybconfName
echo ' label=Linux' >> $ybconfName
echo ' read-only' >> $ybconfName
echo ' initrd=/boot/initrd.img' >> $ybconfName
echo ' append="quiet splash"' >> $ybconfName
echo >> $ybconfName
echo 'image=/boot/vmlinux.old' >> $ybconfName
echo ' label=old' >> $ybconfName
echo ' read-only' >> $ybconfName
echo ' initrd=/boot/initrd.img.old' >> $ybconfName
echo ' append="quiet splash"' >> $ybconfName
}
genFstab () {
# expect linux partition uuid and swap partition UUIDs as arguments;
# write a candidate /etc/fstab file using the target platform values for
# swap partition device name and uuid, and linux root partition device
# name and uuid.
local linuxuuid swapuuid
linuxuuid=$1
swapuuid=$2
echo '# /etc/fstab: static file system information.' > $fstabName
echo '#' >> $fstabName
echo '# <file system> <mount point> <type> <options> <dump> <pass>' >> $fstabName
echo 'proc /proc proc defaults 0 0' >> $fstabName
echo "# $actuallinuxpart" >> $fstabName
echo "UUID=$linuxuuid / ext3 defaults,errors=remount-ro 0 1" >> $fstabName
echo "# $actualswappart" >> $fstabName
echo "UUID=$swapuuid none swap sw 0 0" >> $fstabName
echo "$actualcdrom /media/cdrom0 udf,iso9660 user,noauto 0 0" >> $fstabName
}
usage () {
# print error message and exit
errExit 2 "usage: copyMacDisk [-t macType] srcdev targetdev"
}
getArgs () {
# parse command line options and arguments
# set values for globals: src, target, macType
while getopts t: f; do
case $f in
t) case $OPTARG in
imac) macType=$OPTARG;;
g3) macType=$OPTARG;;
g4) macType=$OPTARG;;
g4q) macType=$OPTARG;;
*) errExit 1 "unrecognized target machine type $OPTARG";;
esac;;
*) usage;;
esac
done
shift `expr $OPTIND - 1`
if [ $# -lt 2 ]; then
usage
else
src=$(basename $1)
target=$(basename $2)
fi
}
verifySource () {
# expect a device name (e.g. hda) as argument;
# test for presence of partition map, and three partitions: boot, linux, swap
# fail/exit if any of these is not there
local src
src=$1
# test: exactly four partitions; successful fdisk has one extra match
n_partitions=$(( $(fdisk -l /dev/$src | grep $src | wc -l) ))
if [ $n_partitions -ne 5 ]; then
errExit 3 "error: $src does not contain 4 partitions"
fi
# test: partition 1 is partition map
part1=$(fdisk -l /dev/$src | grep ${src}1)
if [ -z "$part1" ]; then
errExit 4 "error: no partition map found on $src"
else
if [ -z "`echo $part1 | grep -i map`" ]; then
errExit 4 "error: no partition map found on $src"
fi
fi
# test: partition 2 is boot partition
part2=$(fdisk -l /dev/$src | grep ${src}2)
if [ -z "$part2" ]; then
errExit 5 "error: no boot partition found on $src"
else
if [ -z "`echo $part2 | grep -i bootstrap`" ]; then
errExit 5 "error: no boot partition found on $src"
fi
fi
# test: partition 3 is linux partition
part3=$(fdisk -l /dev/$src | grep ${src}3)
if [ -z "$part3" ]; then
errExit 6 "error: no linux partition found on $src"
else
if [ -z "`echo $part3 | grep -i native`" ]; then
errExit 6 "error: no linux partition found on $src"
fi
fi
# test: partition 4 is swap partition
part4=$(fdisk -l /dev/$src | grep ${src}4)
if [ -z "$part4" ]; then
errExit 7 "error: no swap partition found on $src"
else
if [ -z "`echo $part4 | grep -i swap`" ]; then
errExit 7 "error: no swap partition found on $src"
fi
fi
}
verifyTarget () {
# expect a device name argument;
# the device is expected to be a 'clean' drive with no partition map
# fail/exit if device does not exist (hdpar failure) or has partitions.
local target
target=$1
# target device has to exist
hdparm -g /dev/$target > /dev/null 2>&1
status=$?
if [ $status -ne 0 ]; then
errExit 8 "error: device $target does not seem to exist"
fi
# target device must have no partitions
n_partitions=$(( $(fdisk -l /dev/$target | grep $target | wc -l) ))
if [ $n_partitions -ne 0 ]; then
errExit 9 "error: there appear to be existing partitions on $target"
fi
}
createPartitions () {
# expect no arguments;
# create an fdisk script, run it, verify that the target linux partition
# was created and create an ext3 filesystem on it.
# run the fdisk script
genScript $script
fdisk /dev/$target < $script
# create an ext3 partition on target linux partition
## make sure it's there
n_partitions=$(( $(fdisk -l /dev/$target | grep $targetlinuxpart | wc -l) ))
if [ $n_partitions -ne 1 ]; then
errExit 10 "error: no linux partition $targetlinuxpart for fs creation"
fi
mkfs.ext3 $targetlinuxpart
# rumor has it that 'mkswap' creates a new UUID
mkswap $targetswappart
}
setupForCopy () {
# verify/create all the necessary mount points using global values
# create mount points as necessary
## linux src
if [ ! -d /mnt/$(basename ${srclinuxpart}) ]; then
mkdir /mnt/$(basename ${srclinuxpart})
fi
## linux target
if [ ! -d /mnt/$(basename ${targetlinuxpart}) ]; then
mkdir /mnt/$(basename ${targetlinuxpart})
fi
## boot target
if [ ! -d /mnt/$(basename ${targetbootpart}) ]; then
mkdir /mnt/$(basename ${targetbootpart})
fi
# mount source and target linux partitions
# mount -t ext3 /dev/$(basename ${srclinuxpart}) /mnt/$(basename ${srclinuxpart})
# status=$?
# if [ $status -ne 0 ]; then
# errExit 11 "error: mount src linux partition failed: /dev/${srclinuxpart} to /mnt/${srclinuxpart}"
# fi
mount -t ext3 -o rw /dev/$(basename ${targetlinuxpart}) /mnt/$(basename ${targetlinuxpart})
status=$?
if [ $status -ne 0 ]; then
errExit 12 "error: mount target linux partition failed: /dev/${targetlinuxpart} to /mnt/${targetlinuxpart}"
fi
}
copyPartitions () {
# expect no arguments;
# using global partition names, copy boot partition with dd, and copy
# linux install image with rsync; verify boot partition by mounting it
# as an hfs filesystem
# dd source boot partition to target boot partition
# dd if=/dev/${srcbootpart} of=/dev/${targetbootpart}
dd if=/root/bootpart.img of=/dev/$(basename ${targetbootpart})
# verify boot partition copy
mount -t hfs /dev/$(basename ${targetbootpart}) /mnt/$(basename ${targetbootpart})
status=$?
if [ $status -ne 0 ]; then
errExit 13 "error: mount target boot partition failed: /dev/${targetbootpart} to /mnt/${targetbootpart}"
else
umount /mnt/$(basename ${targetbootpart})
fi
# rsync linux source root to linux target
# rsync -a /mnt/${src}/ /mnt/${targetlinuxpart}/
rsync -av /root/rootdir/ /mnt/$(basename ${targetlinuxpart})/
status=$?
if [ $status -ne 0 ]; then
errExit 14 "error: linux partition copy failed"
else
umount /mnt/$(basename ${targetlinuxpart})
fi
}
tweakFilesForTargetMachine () {
# expect a platform selector as an argument;
# select an OF device-tree definition for the target platform boot-device,
# and capture the UUIDs of the target drive's linux and swap partitions;
# use those values to generate yaboot.conf and fstab files.
local macType
macType=$1
# echo "target machine is $macType"
# OF path to target boot partition. This must be explicit, since the
# assumption is that this host is not, in general, the target
case $mactype in
imac) bootDevice="/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:";;
g3) bootDevice="/pci@80000000/pci-bridge@d/pci-ata@1/@0/disk@0:";;
g4) bootDevice="/pci@f2000000/pci-bridge@d/mac-io@7/ata-4@1f000/disk@0:";;
g4q) bootDevice="/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:";;
*) bootDevice="hd:";;
esac
# UUID of targetlinux and targetswap partitions
linuxuuid=$(vol_id ${targetlinuxpart} | grep -i uuid | cut -d'=' -f2)
swapuuid=$(vol_id ${targetswappart} | grep -i uuid | cut -d'=' -f2)
genYbConf $bootDevice
genFstab $linuxuuid $swapuuid
}
###########################
# main #
###########################
# first of all, best be root to do this
if [ $(whoami) != 'root' ]; then
errExit 1 "You must be root to run this script; try using sudo"
fi
# var defs
script="/tmp/fdisk.script"
ybconfName="/tmp/yaboot.conf"
fstabName="/tmp/fstab"
bootpart=2
linuxpart=3
swappart=4
getArgs $@
srcbootpart=/dev/${src}${bootpart}
srcswappart=/dev/${src}${swappart}
targetbootpart=/dev/${target}${bootpart}
targetswappart=/dev/${target}${swappart}
srclinuxpart=/dev/${src}${linuxpart}
targetlinuxpart=/dev/${target}${linuxpart}
case $macType in
imac) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdb ;;
g3) actuallinuxpart=/dev/hdc3 ;
actualswappart=/dev/hdc4 ;
actualbootpart=/dev/hdc2 ;
actualcdrom=/dev/hda ;;
g4) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
g4q) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
*) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
esac
verifySource ${src}
verifyTarget ${target}
createPartitions
setupForCopy
copyPartitions
if [ $macType ]; then
tweakFilesForTargetMachine $macType
fi
exit 0
genMacDisk.sh
This should be the current working version, if I have been diligent with updates. Theyaboot.conf and fstab modifiers have been added.
#!/bin/sh
#
# usage:
# genMacDisk [-t macType] source-device target-device
# -t macType tweak the relevant files for the target environment
#
# Replicate a Mac Ubuntu disk onto a 'clean' disk; this script assumes
# that the source is a complete installation in a single directory,
# /root/rootdir/, and a boot partition image in /root/bootpart.img. The
# target device is expected to be a 'clean' disk with no partition map.
#
# 1. Take one argument, a target device, and an option specifying the
# target platform
# 2. Verify that the target device is a 'clean' disk
# 3. Create partitions on the target device
# 4. Create an ext3 filesystem on the linux partition of the target device
# 5. Use dd to copy the source boot partition to the target boot partition
# [There is an alternative: use 'mkofboot' to create an populate the
# target boo:t partition. In that case this step wouldn't happen until
# until after fstab and yaboot.conf are modified.]
# 6. Use rsync to copy the source linux installation directory to the target
# linux partition
# 7. modify fstab and yaboot.conf files for target machine environment
# [see step 6]
errExit () {
# expect an error number and message string
# show the message, exit with the error number as exit status
local errno msg
errno=$1
msg=$2
echo $msg
exit $errno
}
genScript () {
# expect a filename string as an argument;
# create an fdisk script file with the argument filename, overwriting
# existing file of same name
local scriptName
scriptName=$1
# length of target drive
## get the hd geometry (hdparm), from that get (awk) the line that has
## "sectors" in it, and spit out the number of sectors from that line
## (sixth field); then remove (cut) the ',' from the end of the number;
## The hd length used for partition length calculations is actually one
## less that the true disk length, since block zero is ignored.
hdlen=$(hdparm -g /dev/$target | awk '/sector/ {print $6}' | cut -d ',' -f 1)
hdlen=$(($hdlen - 1))
# starts and lengths for boot, linux and swap partitions
#
# known values
mapstart=1
maplen=63
bootlen=1954
swaplen=1494848
#calculated values
bootstart=$(($mapstart + $maplen))
linuxstart=$(($bootstart + $bootlen))
linuxlen=$(($hdlen-($maplen + $bootlen + $swaplen)))
swapstart=$(($linuxstart+$linuxlen))
# generate and write the commands, creating the script file
#
# initialize partition table, answer disk length query, and show the result
echo i > $scriptName
echo "" >> $scriptName
echo p >> $scriptName
# create a boot partition with explicit partition size/type, and show result
echo C >> $scriptName
echo $bootstart >> $scriptName
echo $bootlen >> $scriptName
echo untitled >> $scriptName
echo Apple_Bootstrap >> $scriptName
echo p >> $scriptName
# create a linux native partition, and show result
echo c >> $scriptName
echo $linuxstart >> $scriptName
echo $linuxlen >> $scriptName
echo untitled >> $scriptName
echo p >> $scriptName
# create the swap partition. and show result
echo c >> $scriptName
echo $swapstart >> $scriptName
echo $swaplen >> $scriptName
echo swap >> $scriptName
echo p >> $scriptName
# write out the partition map and confirm
echo w >> $scriptName
echo yes >> $scriptName
# we done partishin' now
echo q >> $scriptName
}
genYbConf () {
# expect a boot-device string formatted as an OF device-tree name;
# write a candidate yaboot.conf file using target platform values for boot device,
# boot partition and linux root partition.
local bootdev
bootdev=$1
echo '## yaboot.conf generated by the Ubuntu installer' > $ybconfName
echo '##' >> $ybconfName
echo '## run: "man yaboot.conf" for details. Do not make changes until you have!!' >> $ybconfName
echo '## see also: /usr/share/doc/yaboot/examples for example configurations.' >> $ybconfName
echo '##' >> $ybconfName
echo '## For a dual-boot menu, add one or more of:' >> $ybconfName
echo '## bsd=/dev/hdaX, macos=/dev/hdaY, macosx=/dev/hdaZ' >> $ybconfName
echo >> $ybconfName
echo "boot=${actualbootpart}" >> $ybconfName
echo "device=${bootdev}" >> $ybconfName
echo 'partition=3' >> $ybconfName
echo "root=${actuallinuxpart}" >> $ybconfName
echo 'timeout=50' >> $ybconfName
echo 'install=/usr/lib/yaboot/yaboot' >> $ybconfName
echo 'magicboot=/usr/lib/yaboot/ofboot' >> $ybconfName
echo 'enablecdboot' >> $ybconfName
echo >> $ybconfName
echo 'image=/boot/vmlinux' >> $ybconfName
echo ' label=Linux' >> $ybconfName
echo ' read-only' >> $ybconfName
echo ' initrd=/boot/initrd.img' >> $ybconfName
echo ' append="quiet splash"' >> $ybconfName
echo >> $ybconfName
echo 'image=/boot/vmlinux.old' >> $ybconfName
echo ' label=old' >> $ybconfName
echo ' read-only' >> $ybconfName
echo ' initrd=/boot/initrd.img.old' >> $ybconfName
echo ' append="quiet splash"' >> $ybconfName
}
genFstab () {
# expect linux partition uuid and swap partition UUIDs as arguments;
# write a candidate /etc/fstab file using the target platform values for
# swap partition device name and uuid, and linux root partition device
# name and uuid.
local linuxuuid swapuuid
linuxuuid=$1
swapuuid=$2
echo '# /etc/fstab: static file system information.' > $fstabName
echo '#' >> $fstabName
echo '# <file system> <mount point> <type> <options> <dump> <pass>' >> $fstabName
echo 'proc /proc proc defaults 0 0' >> $fstabName
echo "# $actuallinuxpart" >> $fstabName
echo "UUID=$linuxuuid / ext3 defaults,errors=remount-ro 0 1" >> $fstabName
echo "# $actualswappart" >> $fstabName
echo "UUID=$swapuuid none swap sw 0 0" >> $fstabName
echo "$actualcdrom /media/cdrom0 udf,iso9660 user,noauto 0 0" >> $fstabName
}
usage () {
# print error message and exit
errExit 2 "usage: copyMacDisk [-t macType] srcdev targetdev"
}
getArgs () {
# parse command line options and arguments
# set values for globals: src, target, macType
while getopts t: f; do
case $f in
t) case $OPTARG in
imac) macType=$OPTARG;;
g3) macType=$OPTARG;;
g4) macType=$OPTARG;;
g4q) macType=$OPTARG;;
*) errExit 1 "unrecognized target machine type $OPTARG";;
esac;;
*) usage;;
esac
done
shift `expr $OPTIND - 1`
if [ $# -lt 1 ]; then
usage
else
target=$(basename $1)
fi
}
verifyTarget () {
# expect a device name argument;
# the device is expected to be a 'clean' drive with no partition map
# fail/exit if device does not exist (hdpar failure) or has partitions.
local target
target=$1
# target device has to exist
hdparm -g /dev/$target > /dev/null 2>&1
status=$?
if [ $status -ne 0 ]; then
errExit 8 "error: device $target does not seem to exist"
fi
# target device must have no partitions
n_partitions=$(( $(fdisk -l /dev/$target | grep $target | wc -l) ))
if [ $n_partitions -ne 0 ]; then
errExit 9 "error: there appear to be existing partitions on $target"
fi
}
createPartitions () {
# expect no arguments;
# create an fdisk script, run it, verify that the target linux partition
# was created and create an ext3 filesystem on it.
# run the fdisk script
genScript $script
fdisk /dev/$target < $script
# create an ext3 partition on target linux partition
## make sure it's there
n_partitions=$(( $(fdisk -l /dev/$target | grep $targetlinuxpart | wc -l) ))
if [ $n_partitions -ne 1 ]; then
errExit 10 "error: no linux partition $targetlinuxpart for fs creation"
fi
mkfs.ext3 $targetlinuxpart
# rumor has it that 'mkswap' creates a new UUID
mkswap $targetswappart
}
setupForCopy () {
# verify/create all the necessary mount points using global values
# create mount points as necessary
## linux target
if [ ! -d /mnt/$(basename ${targetlinuxpart}) ]; then
mkdir /mnt/$(basename ${targetlinuxpart})
fi
## boot target
if [ ! -d /mnt/$(basename ${targetbootpart}) ]; then
mkdir /mnt/$(basename ${targetbootpart})
fi
# mount target linux partition
mount -t ext3 -o rw /dev/$(basename ${targetlinuxpart}) /mnt/$(basename ${targetlinuxpart})
status=$?
if [ $status -ne 0 ]; then
errExit 12 "error: mount target linux partition failed: /dev/${targetlinuxpart} to /mnt/${targetlinuxpart}"
fi
}
copyPartitions () {
# expect no arguments;
# using global partition names, copy boot partition with dd, and copy
# linux install image with rsync; verify boot partition by mounting it
# as an hfs filesystem
# dd source boot partition image to target boot partition
dd if=${bootpartImg} of=/dev/$(basename ${targetbootpart})
# verify boot partition copy
mount -t hfs /dev/$(basename ${targetbootpart}) /mnt/$(basename ${targetbootpart})
status=$?
if [ $status -ne 0 ]; then
errExit 13 "error: mount target boot partition failed: /dev/${targetbootpart} to /mnt/${targetbootpart}"
else
umount /mnt/$(basename ${targetbootpart})
fi
# rsync linux source root directory to linux target partition
rsync -av ${linuxImg}/ /mnt/$(basename ${targetlinuxpart})/
status=$?
if [ $status -ne 0 ]; then
errExit 14 "error: linux partition copy failed"
else
umount /mnt/$(basename ${targetlinuxpart})
fi
}
tweakFilesForTargetMachine () {
# expect a platform selector as an argument;
# select an OF device-tree definition for the target platform boot-device,
# and capture the UUIDs of the target drive's linux and swap partitions;
# use those values to generate yaboot.conf and fstab files.
local macType
macType=$1
# echo "target machine is $macType"
# OF path to target boot partition. This must be explicit, since the
# assumption is that this host is not, in general, the target
case $mactype in
imac) bootDevice="/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:";;
g3) bootDevice="/pci@80000000/pci-bridge@d/pci-ata@1/@0/disk@0:";;
g4) bootDevice="/pci@f2000000/pci-bridge@d/mac-io@7/ata-4@1f000/disk@0:";;
g4q) bootDevice="/pci@f2000000/mac-io@17/ata-4@1f000/disk@0:";;
*) bootDevice="hd:";;
esac
# UUID of targetlinux and targetswap partitions
linuxuuid=$(vol_id ${targetlinuxpart} | grep -i uuid | cut -d'=' -f2)
swapuuid=$(vol_id ${targetswappart} | grep -i uuid | cut -d'=' -f2)
genYbConf $bootDevice
genFstab $linuxuuid $swapuuid
mount -t ext3 -o rw /dev/$(basename ${targetlinuxpart}) /mnt/$(basename ${targetlinuxpart})
cp $ybconfName /mnt/$(basename ${targetlinuxpart})/etc/yaboot.conf
cp $fstabName /mnt/$(basename ${targetlinuxpart})/etc/fstab
mkofboot -b /dev/$(basename ${targetbootpart}) -o $bootDevice -C /mnt/$(basename ${targetlinuxpart})/etc/yaboot.conf --nonvram
status=$?
if [ $status -ne 0 ]; then
errExit 15 "error: failed to update boot partition"
fi
}
###########################
# main #
###########################
# first of all, best be root to do this
if [ $(whoami) != 'root' ]; then
errExit 1 "You must be root to run this script; try using sudo"
fi
# var defs
linuxImg=/root/rootdir
bootpartImg=/root/bootpart.img
script="/tmp/fdisk.script"
ybconfName="/tmp/yaboot.conf"
fstabName="/tmp/fstab"
bootpart=2
linuxpart=3
swappart=4
getArgs $@
targetbootpart=/dev/${target}${bootpart}
targetswappart=/dev/${target}${swappart}
targetlinuxpart=/dev/${target}${linuxpart}
case $macType in
imac) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdb ;;
g3) actuallinuxpart=/dev/hdc3 ;
actualswappart=/dev/hdc4 ;
actualbootpart=/dev/hdc2 ;
actualcdrom=/dev/hda ;;
g4) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
g4q) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
*) actuallinuxpart=/dev/hda3 ;
actualswappart=/dev/hda4 ;
actualbootpart=/dev/hda2 ;
actualcdrom=/dev/hdc ;;
esac
verifyTarget ${target}
createPartitions
setupForCopy
copyPartitions
if [ $macType ]; then
tweakFilesForTargetMachine $macType
fi
exit 0
shrink_initrd.sh
#!/bin/bash # # in case you want to know too much about why things aren't working: #set -x #set -v # # The goal here is to translate 'initrd.gz', a gzipped cpio archive, # to CRAMFS version of the same thing, while reducing the size of the # resulting file to something under 6MB. The reasons for doing so # are discussed elsewhere. See, for example, # http://wiki.freegeek.org/index.php?title=User:Tonyr/Journal/Apr07&action=edit§ion=9 # and other related entries. # # The file to be translated is one of the netboot files in Ubuntu distributions. The files # for the Ubuntu Feisty(7.04) release are available at # http://archive.ubuntu.com/ubuntu/dists/feisty/main/installer-powerpc/current/images/powerpc/netboot # The files for Edgy(6.10) and Gutsy(7.10 pre-release) are also available. # # This script expects one argument, a filename, which is expected to be an initrd file # in one of the formats 'gzipped cpio archive', 'cpio archive', or CRAMFS. The directory # structure is extracted, a purely subjective set of files is removed from the resulting # direcortory tree, and that result is re-compressed into both gzipped cpio and CRAMFS # forms, which are placed in the same directory as the original input file. # (As of 18Sep07, the CRAMFS extraction is not implemented, but a commented-out # section of code suggests the process for that.) # # usage: shrink_initrd.sh file_pathname # # input: a compressed initial ram file system in gzipped cpio format or # CRAMFS format # output: newinitrd.gz, a smaller gzipped cpio archive version of the input # newinitrd.img, a CRAMFS version of the same # (in the same directory as the original input file) # # The input filename may be in either relative or absolute pathname form. # So, what are we gonna do? # 1. extract the initrd file system image from its compressed form # 2. remove enough extraneous files to allow a rebuilt initrd image # to be smaller than 6MB. # 3. generate a CRAMFS initrd image and a gzipped cpio archive from # the reduced initrd files system # # housekeeping functions function cleanup { echo "cleaning up..." rm -rf $DIR exit } function cleanup_on_interrupt { echo "cleaning up..." rm -rf $DIR rm -rf $NEW_INITRD_GZ rm -rf $NEW_INITRD_IMG exit } # leave no trace upon external interruption trap cleanup_on_interrupt SIGHUP SIGINT SIGTERM # I suggest running this as root if [ $(whoami) != root ]; then echo "I suggest running this script as root, like, y'know, with sudo" exit fi # best have a file argument if [ $# -lt 1 ] ; then echo "usage: shrink <initrd_file_name>" exit fi # now let's define some useful file names; # the new image files will show up in the same directory as the # original image. INITRD_FILE=$1 INITRD_FILE_DIR=$(dirname $INITRD_FILE) # at various points down the road we're gonna wanna know where we started HERE=$(pwd) # I'd really like the new file names to be absolute if [ "${INITRD_FILE_DIR:0:1}" != "/" ]; then INITRD_FILE_DIR=$HERE/$INITRD_FILE_DIR fi NEW_INITRD_GZ="$INITRD_FILE_DIR/newinitrd.gz" NEW_INITRD_IMG="$INITRD_FILE_DIR/newinitrd.img" # and mkcramfs must be available if [ "$(which mkcramfs)" = "" ]; then echo "no cramfs tools found, try installing package cramfsprogs" exit fi # file argument should at least be a regular file if [ ! -f $1 ]; then echo "cannot find regular file $INITRD_FILE" exit else echo "processing file $INITRD_FILE" fi # It should be either a cpio archive, a gzipped cpio archive, # or a CRAMFS image ftype=none fdesc=$(file $INITRD_FILE) if echo "$fdesc" | grep -q gzip; then fdesc=$(file -z $INITRD_FILE) if echo "$fdesc" | grep -q "cpio archive" ; then ftype=zcpio fi elif echo "$fdesc" | grep -q "Linux Compressed ROM File System"; then ftype=cramfs elif echo "$fdesc" | grep -q "cpio archive"; then ftype=cpio fi # hmmm...the input file is not what we were expecting if [ $ftype = none ]; then echo "$INITRD_FILE does not appear to be cpio or cramfs" exit fi # report the input file size echo -n "compressed size before: " du -s $INITRD_FILE # now make a temporary directory to hold the initrd directory tree INITRD_DIR=initrd_$$ DIR=/tmp/$INITRD_DIR mkdir $DIR # and extract the initrd directory tree to the temp directory case $ftype in cpio) echo "extracting file $INITRD_FILE to $DIR" cat $INITRD_FILE | (cd $DIR; cpio -i ) ;; zcpio) echo "extracting gzipped cpio file $INITRD_FILE to $DIR" gunzip -c $INITRD_FILE | (cd $DIR; cpio -i ) ;; cramfs) echo "cramfs extraction not implemented yet"; cleanup ## well, here's a guess about how to do this # mkdir /mnt/tmpcramfs # mount -t cramfs -o loop $INITRD_FILE /mnt/tmpcramfs # cd /mnt/tmpcramfs # find . -depth -print | cpio -p --make-directories $DIR # umount /mnt/tmpcramfs # cd $HERE ;; esac # I'm assuming that the files I'm interested in are in sub-directories # of the lib/modules/<kernel-version> directory in the initrd tree. # This is not a definitive test, as it only looks for ANY directory # in the expected location. There is probably a better way, but it is my # observation that the <kernel-version> will be the version at major # release time, not necessarily the actual (updated?) kernel version. kver=$(ls $DIR/lib/modules) if [ "$kver" = "" ]; then echo "oops, there doesn't seem to be a kernel version modules directory" cleanup exit fi # ok, so now we have a reasonable expectation of doing something useful: # removing some files named in a list. I selected the items on this list in # a purely subjective manner, anything that seemed irrelevant to the task at # hand, namely, netboot installation of PPC Ubuntu on Macs in the MacBuild # area at FreeGeek. Any usefulness beyond that is serendipity. On the other # hand, you can modify this list to suit your own needs. # # For my purposes, what is left is the sungem driver and some other drivers # whose name starts with 'sun' and the tulip drivers for the DEC controllers. file=( \ lib/firmware/$kver/atmel_at76c502_3com.bin \ lib/firmware/$kver/atmel_at76c502_3com-wpa.bin \ lib/firmware/$kver/atmel_at76c502.bin \ lib/firmware/$kver/atmel_at76c502d.bin \ lib/firmware/$kver/atmel_at76c502d-wpa.bin \ lib/firmware/$kver/atmel_at76c502e.bin \ lib/firmware/$kver/atmel_at76c502e-wpa.bin \ lib/firmware/$kver/atmel_at76c502-wpa.bin \ lib/firmware/$kver/atmel_at76c503-i3861.bin \ lib/firmware/$kver/atmel_at76c503-i3863.bin \ lib/firmware/$kver/atmel_at76c503-rfmd-0.90.2-140.bin \ lib/firmware/$kver/atmel_at76c503-rfmd-acc.bin \ lib/firmware/$kver/atmel_at76c503-rfmd.bin \ lib/firmware/$kver/atmel_at76c504_2958-wpa.bin \ lib/firmware/$kver/atmel_at76c504a_2958-wpa.bin \ lib/firmware/$kver/atmel_at76c504.bin \ lib/firmware/$kver/atmel_at76c504c-wpa.bin \ lib/firmware/$kver/atmel_at76c505a-rfmd2958.bin \ lib/firmware/$kver/atmel_at76c505-rfmd2958.bin \ lib/firmware/$kver/atmel_at76c505-rfmd.bin \ lib/firmware/$kver/atmel_at76c506.bin \ lib/firmware/$kver/atmel_at76c506-wpa.bin \ lib/firmware/$kver/ipw2100-1.3.fw \ lib/firmware/$kver/ipw2100-1.3-i.fw \ lib/firmware/$kver/ipw2100-1.3-p.fw \ lib/firmware/$kver/ipw2200-bss.fw \ lib/firmware/$kver/ipw2200-ibss.fw \ lib/firmware/$kver/ipw2200-sniffer.fw \ lib/modules/$kver/kernel/drivers/net/3c59x.ko \ lib/modules/$kver/kernel/drivers/net/8139cp.ko \ lib/modules/$kver/kernel/drivers/net/8139too.ko \ lib/modules/$kver/kernel/drivers/net/8390.ko \ lib/modules/$kver/kernel/drivers/net/amd8111e.ko \ lib/modules/$kver/kernel/drivers/net/appletalk \ lib/modules/$kver/kernel/drivers/net/arcnet \ lib/modules/$kver/kernel/drivers/net/b44.ko \ lib/modules/$kver/kernel/drivers/net/bmac.ko \ lib/modules/$kver/kernel/drivers/net/bnx2.ko \ lib/modules/$kver/kernel/drivers/net/bonding \ lib/modules/$kver/kernel/drivers/net/cassini.ko \ lib/modules/$kver/kernel/drivers/net/de600.ko \ lib/modules/$kver/kernel/drivers/net/de620.ko \ lib/modules/$kver/kernel/drivers/net/defxx.ko \ lib/modules/$kver/kernel/drivers/net/dl2k.ko \ lib/modules/$kver/kernel/drivers/net/e1000 \ lib/modules/$kver/kernel/drivers/net/e100.ko \ lib/modules/$kver/kernel/drivers/net/eepro100.ko \ lib/modules/$kver/kernel/drivers/net/epic100.ko \ lib/modules/$kver/kernel/drivers/net/eql.ko \ lib/modules/$kver/kernel/drivers/net/fealnx.ko \ lib/modules/$kver/kernel/drivers/net/forcedeth.ko \ lib/modules/$kver/kernel/drivers/net/hamachi.ko \ lib/modules/$kver/kernel/drivers/net/hp100.ko \ lib/modules/$kver/kernel/drivers/net/ixgb \ lib/modules/$kver/kernel/drivers/net/mace.ko \ lib/modules/$kver/kernel/drivers/net/mii.ko \ lib/modules/$kver/kernel/drivers/net/mv643xx_eth.ko \ lib/modules/$kver/kernel/drivers/net/natsemi.ko \ lib/modules/$kver/kernel/drivers/net/ne2k-pci.ko \ lib/modules/$kver/kernel/drivers/net/ns83820.ko \ lib/modules/$kver/kernel/drivers/net/pcmcia \ lib/modules/$kver/kernel/drivers/net/pcnet32.ko \ lib/modules/$kver/kernel/drivers/net/r8169.ko \ lib/modules/$kver/kernel/drivers/net/rrunner.ko \ lib/modules/$kver/kernel/drivers/net/s2io.ko \ lib/modules/$kver/kernel/drivers/net/shaper.ko \ lib/modules/$kver/kernel/drivers/net/sis190.ko \ lib/modules/$kver/kernel/drivers/net/sis900.ko \ lib/modules/$kver/kernel/drivers/net/sk98lin \ lib/modules/$kver/kernel/drivers/net/skfp \ lib/modules/$kver/kernel/drivers/net/skge.ko \ lib/modules/$kver/kernel/drivers/net/sky2.ko \ lib/modules/$kver/kernel/drivers/net/starfire.ko \ lib/modules/$kver/kernel/drivers/net/tg3.ko \ lib/modules/$kver/kernel/drivers/net/tlan.ko \ lib/modules/$kver/kernel/drivers/net/tokenring \ lib/modules/$kver/kernel/drivers/net/tun.ko \ lib/modules/$kver/kernel/drivers/net/typhoon.ko \ lib/modules/$kver/kernel/drivers/net/via-rhine.ko \ lib/modules/$kver/kernel/drivers/net/via-velocity.ko \ lib/modules/$kver/kernel/drivers/net/wireless/airo_cs.ko \ lib/modules/$kver/kernel/drivers/net/wireless/airo.ko \ lib/modules/$kver/kernel/drivers/net/wireless/airport.ko \ lib/modules/$kver/kernel/drivers/net/wireless/atmel_cs.ko \ lib/modules/$kver/kernel/drivers/net/wireless/atmel.ko \ lib/modules/$kver/kernel/drivers/net/wireless/atmel_pci.ko \ lib/modules/$kver/kernel/drivers/net/wireless/ipw2100.ko \ lib/modules/$kver/kernel/drivers/net/wireless/ipw2200.ko \ lib/modules/$kver/kernel/drivers/net/wireless/netwave_cs.ko \ lib/modules/$kver/kernel/drivers/net/wireless/ray_cs.ko \ lib/modules/$kver/kernel/drivers/net/wireless/strip.ko \ lib/modules/$kver/kernel/drivers/net/wireless/wavelan_cs.ko \ lib/modules/$kver/kernel/drivers/net/wireless/wl3501_cs.ko \ lib/modules/$kver/kernel/drivers/net/yellowfin.ko ) # how big is the actual data before removals? echo -n "raw size before: " du -s $DIR # let's crank through the list now, obliterating as we go for i in $( seq 0 $((${#file[@]} - 1))); do rm -rf $DIR/${file[$i]} # echo $DIR/${file[$i]} done # how big is the actual data after removals? echo -n "raw size after: " du -s $DIR # now recompress the result with gzip... cd $DIR echo "making new gzipped initrd in $NEW_INITRD_GZ" find . -depth -print | cpio -oc | gzip -c > $NEW_INITRD_GZ chown ${SUDO_USER}.adm $NEW_INITRD_GZ # how big is the compressed cpio file after removals? echo -n "gzip compressed size after: " du -s $NEW_INITRD_GZ # ...and with mkcramfs echo "making new cramfs initrd in $NEW_INITRD_IMG" mkcramfs $DIR $NEW_INITRD_IMG # I'm not gonna leave the resulting files owned by root, but who should own them? chown ${SUDO_USER}.adm $NEW_INITRD_IMG # and how big is the compressed cramfs file after removals? echo -n "cramfs compressed size after: " du -s $NEW_INITRD_IMG cleanup