Difference between revisions of "Mac Build Scripts"
Jump to navigation
Jump to search
(→Replicate Mac Ubuntu Disk: Disk to Disk: bye-bye) |
(delete Replicate Disk to Disk, obsolete) |
||
Line 1: | Line 1: | ||
==Generate fdisk script== | ==Generate fdisk script== | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
==Replicate Mac Ubuntu Disk: Host to Disk== | ==Replicate Mac Ubuntu Disk: Host to Disk== | ||
This is the same script as above, but hacked to use a bootpartition image and a copy of the root filesystem, both resident on the host in directory '''/root'''. Still needs boot partition mods for correct UUIDs ('''ybin''' or '''mkofboot'''), and fstab replacement. | This is the same script as above, but hacked to use a bootpartition image and a copy of the root filesystem, both resident on the host in directory '''/root'''. Still needs boot partition mods for correct UUIDs ('''ybin''' or '''mkofboot'''), and fstab replacement. |
Revision as of 22:59, 19 November 2007
Generate fdisk script
Replicate Mac Ubuntu Disk: Host to Disk
This is the same script as above, but hacked to use a bootpartition image and a copy of the root filesystem, both resident on the host in directory /root. Still needs boot partition mods for correct UUIDs (ybin or mkofboot), and fstab replacement.
#!/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
The same hacked script as above, but cleaned up somewhat. Still without yaboot.conf and fstab modifiers.
#!/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