#!/bin/bash␊ |
␊ |
diskloader="/usr/standalone/i386/boot0"␊ |
diskloaderdualboot="/usr/standalone/i386/boot0hfs"␊ |
partitionloaderhfs="/usr/standalone/i386/boot1h"␊ |
partitionloaderfat="/usr/standalone/i386/boot1f32"␊ |
filesystemloader="/usr/standalone/i386/boot"␊ |
bootervolumename="EFI"␊ |
booterextensions="Extra/Extensions"␊ |
␊ |
bootresources="${0%/*}"␊ |
␊ |
diskmicrocodetype[1]="GRUB,47525542"␊ |
diskmicrocodetype[2]="LILO,4c494c4f"␊ |
␊ |
start ()␊ |
{␊ |
# $1 volume␊ |
␊ |
osxvolume="${@}"␊ |
␊ |
if [ -z "${osxvolume}" ]; then␊ |
␉echo␊ |
␉echo "Cannot find the volume. Exiting."␊ |
␉exit␊ |
fi␊ |
␊ |
bootdev=$( df "${osxvolume}" | sed -n '2p' | awk '{print $1}' )␊ |
␊ |
if [ "${bootdev}" = "${bootdev#*disk*s}" ]; then␊ |
␉echo␊ |
␉echo "ERROR Volume does not use slices."␊ |
␉echo "Volume may be stored on a RAID array."␊ |
␉echo␊ |
␉exit␊ |
fi␊ |
␊ |
bootuuid=$( diskutil info "$bootdev" | grep Volume\ UUID | awk {'print $3'} )␊ |
partitiontable=$( diskutil list ${bootdev%s*} | sed -n '3p' | awk '{print $2}' )␊ |
␊ |
if [ ${partitiontable} != "GUID_partition_scheme" ]; then␊ |
␉echo␊ |
␉echo "ERROR Volume is not on a GPT partitioned disc."␊ |
␉echo␊ |
␉exit␊ |
fi␊ |
␊ |
echo "==============================================="␊ |
echo "Partition Type Identified:"␊ |
echo "**************************"␊ |
echo "GPT found."␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Installer Variables Part 1:"␊ |
echo "***************************"␊ |
echo "OS X Volume is ${osxvolume}"␊ |
echo "OX X Volume device is ${bootdev}"␊ |
echo "OS X Volume UUID is ${bootuuid}"␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
bootvolume="/Volumes/$bootervolumename"␊ |
bootdev=${bootdev%s*}s1␊ |
bootrdev=${bootdev/disk/rdisk}␊ |
bootdisk=${bootdev%s*}␊ |
bootrdisk=${bootdisk/disk/rdisk}␊ |
bootslice=${bootdev#*disk*s}␊ |
␊ |
echo "==============================================="␊ |
echo "Installer Variables Part 2:"␊ |
echo "***************************"␊ |
echo "EFI Volume device is ${bootdev}"␊ |
echo "EFI Volume raw device is ${bootrdev}"␊ |
echo "EFI Volume slice is ${bootslice}"␊ |
echo "Disk device is ${bootdisk}"␊ |
echo "Disk raw device is ${bootrdisk}"␊ |
echo "Disk loader normal is ${diskloader}"␊ |
echo "Disk loader dual boot is ${diskloaderdualboot}"␊ |
echo "Partition loader HFS is ${partitionloaderhfs}"␊ |
echo "Partition loader FAT is ${partitionloaderfat}"␊ |
echo "Filesystem loader is ${filesystemloader}"␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
checkdiskmicrocodetype ()␊ |
{␊ |
echo "==============================================="␊ |
echo "Diskmicrocodetype:"␊ |
echo "******************"␊ |
␊ |
diskmicrocode=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
␊ |
diskmicrocodetypecounter=0␊ |
while [ ${diskmicrocodetypecounter} -lt ${#diskmicrocodetype[@]} ]; do␊ |
diskmicrocodetypecounter=$(( ${diskmicrocodetypecounter} + 1 ))␊ |
diskmicrocodetypeid=${diskmicrocodetype[${diskmicrocodetypecounter}]#*,}␊ |
if [ ! "${diskmicrocode}" = "${diskmicrocode/${diskmicrocodetypeid}/}" ]; then␊ |
echo "${diskmicrocodetype[${diskmicrocodetypecounter}]%,*} found."␊ |
␉else␊ |
␉␉echo "Didn't find a match for ${diskmicrocodetype[${diskmicrocodetypecounter}]%,*}"␊ |
fi␊ |
done␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
}␊ |
␊ |
␊ |
checkdiskmicrocode ()␊ |
{␊ |
echo "==============================================="␊ |
echo "Diskmicrocode:"␊ |
echo "*************"␊ |
␊ |
# Note: The checks for Boot0 and Boot0hfs assume the code doesn't change!!␊ |
␊ |
# 1 action ( check or set )␊ |
␊ |
diskmicrocode=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
diskmicrocodemd5=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=1 bs=437 | md5 )␊ |
␊ |
if [ $( echo "${diskmicrocode}" | awk -F0 '{print NF-1}' ) = 874 ]; then␊ |
␉echo "Diskmicrocode = 874 (Which means the first 437 bytes of the MBR Disk Sector is blank)"␊ |
␉if [ "${1}" = "set" ]; then␊ |
␉␉echo "No disk microcode found. Updating."␊ |
␉␉diskupdate=true␊ |
␉␉echo "diskupdate is now set to true."␊ |
␉else␊ |
␉␉echo "No disk microcode found."␊ |
␉fi␊ |
else␊ |
␉# There is already something on the MBR ␊ |
␉if [ ${1} = set ]; then␊ |
␊ |
␉␉# See if a Windows bootloader already exists␊ |
␉␉windowsloader=$( dd 2>/dev/null if=${bootdisk} count=4 bs=1 | xxd | awk '{print $2$3}' )␊ |
␉␉if [ "${windowsloader}" == "33c08ed0" ] ; then␊ |
␉␉␉echo "Found existing Windows Boot Loader"␊ |
␉␉␉echo "Will replace loader with Boot0hfs"␊ |
␉␉␉diskupdate=true␊ |
␉␉␉echo "diskupdate is now set to true."␊ |
␉␉fi␊ |
␊ |
␉␉# See if a Chameleon stage0 boot file already exists␊ |
␉␉stage0type=$( dd 2>/dev/null if=${bootdisk} count=3 bs=1 skip=105 | xxd | awk '{print $2$3}' )␊ |
␉␉if [ "${stage0type}" == "0b807c" ] || [ "${stage0type}" == "0a803c" ] ; then␊ |
␊ |
␉␉␉echo "Found existing Chameleon Stage 0 Loader"␊ |
␉␉␉# if found Boot0HFS without a Windows installation set diskupdate to true␊ |
␉␉␉if [ "${stage0type}" == "0b807c" ] && [ "${disksignature}" == "00000000" ]; then␊ |
␉␉␉␉echo "Found existing Chameleon Boot0HFS without a Windows installation"␊ |
␉␉␉␉echo "Will replace loader with Boot0"␊ |
␉␉␉␉diskupdate=true␊ |
␉␉␉␉echo "diskupdate is now set to true."␊ |
␉␉␉fi␊ |
␊ |
␉␉␉# if found Boot0 with a Windows installation set diskupdate to true␊ |
␉␉␉if [ "${stage0type}" == "0a803c" ] && [ "${disksignature}" != "00000000" ]; then␊ |
␉␉␉␉echo "Found existing Chameleon Boot0 with a Windows installation"␊ |
␉␉␉␉echo "Will replace loader with Boot0hfs"␊ |
␉␉␉␉diskupdate=true␊ |
␉␉␉␉echo "diskupdate is now set to true."␊ |
␉␉␉fi␊ |
␉␉fi␊ |
␉␊ |
␉␉# If neither a Windows or Chameleon Boot Loader exists␊ |
␉␉if [ "${stage0type}" != "0b807c" ] && [ "${stage0type}" != "0a803c" ] && [ "${windowsloader}" != "33c08ed0" ] ; then␊ |
␉␉␉test=$(echo "${diskmicrocode}" | awk -F0 '{print NF-1}' )␊ |
␉␉␉echo "Disk microcode found: ${test} - Preserving."␊ |
␉␉␉echo "diskupdate is left at false"␊ |
␉␉fi␊ |
␉else␊ |
␉␉test=$(echo "${diskmicrocode}" | awk -F0 '{print NF-1}' )␊ |
␉␉echo "Disk microcode found: ${test}"␊ |
␉fi␊ |
fi␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
}␊ |
␊ |
␊ |
checkdisksignature ()␊ |
{␊ |
echo "==============================================="␊ |
echo "Find Disk Signature:"␊ |
echo "*************"␊ |
disksignature=$( dd 2>/dev/null if=${bootdisk} count=1 | dd 2>/dev/null count=4 bs=1 skip=440 | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
␊ |
echo "${disksignature}"␊ |
␊ |
if [ $disksignature = "00000000" ]; then␊ |
␉echo "Just Zero's found meaning Windows isn't installed."␊ |
else␊ |
␉echo "Non Zero means we've found a Windows installation"␊ |
fi␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
}␊ |
␊ |
␊ |
checkpartitionbootcode ()␊ |
{␊ |
echo "==============================================="␊ |
echo "Find Partition Bootcode:"␊ |
echo "************************"␊ |
␊ |
# 1 action ( check or set )␊ |
␊ |
partitionbootcode=$( dd if=${bootrdev} count=1 2>/dev/null | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
partitionbootcodeextended=$( dd if=${bootrdev} count=1 skip=1 2>/dev/null | perl -ne '@a=split"";for(@a){printf"%02x",ord}' )␊ |
␊ |
if [ $( echo "${partitionbootcode}" | awk -F0 '{print NF-1}' ) = 1024 ]; then␊ |
␉echo "partitionbootcode = 1024 (Which means the whole 512 bytes of the MBR Disk Sector is blank)"␊ |
␉if [ "${1}" = "set" ]; then␊ |
␉␉echo "No partition bootcode found. Updating."␊ |
␉else␊ |
␉␉echo "No partition bootcode found."␊ |
␉fi␊ |
else␊ |
␉if [ "${1}" = "set" ]; then␊ |
␉␉echo "Partition bootcode found. Overwriting."␊ |
␉else␊ |
␉␉echo "Partition bootcode found."␊ |
␉fi␊ |
␉if [ $( echo "${partitionbootcodeextended}" | awk -F0 '{print NF-1}' ) = 1024 ]; then␊ |
␉␉partitionbootcodemd5=$( dd 2>/dev/null if=${bootrdev} count=1 | md5 )␊ |
␉else␊ |
␉␉partitionbootcodemd5=$( dd 2>/dev/null if=${bootrdev} count=2 | md5 )␊ |
␉␉echo "Partition bootcode is dual sector."␊ |
␉fi␊ |
␉echo "Partition bootcode MD5 is ${partitionbootcodemd5}"␊ |
fi␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
}␊ |
␊ |
␊ |
#checkpartitionactive ()␊ |
#{␊ |
#partitionactive=$( fdisk440 -d ${bootrdisk} | grep -n "*" | awk -F: '{print $1}')␊ |
␊ |
#if [ -n "${partitionactive}" ]; then ␊ |
#␉echo "Partition flagged active is ${partitionactive}"␊ |
#else␊ |
#␉echo "No partition flagged active."␊ |
#fi␊ |
␊ |
#}␊ |
}␊ |
␊ |
␊ |
start ${3}␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Check the format of the EFI partition"␊ |
echo "*************************************"␊ |
␊ |
if [ "$( df | grep ${bootdev} )" ]; then␊ |
␉echo "${bootdev} is currently mounted, so un-mounting it"␊ |
␉umount -f ${bootdev}␊ |
else␊ |
␉echo "EFI partition is currently not mounted"␊ |
fi ␊ |
␊ |
#if [[ `dd if=/dev/disk${1}s1 count=8 bs=1 skip=82 | uuencode -m -|head -n 2|tail -n 1` != "RkFUMzIgICA=" ]]; then␊ |
#␉echo "${bootdev} isn't a FAT32 partition"␊ |
#␉newfs_msdos -v "${bootervolumename}" "${bootdev}"␊ |
#fi ␊ |
␊ |
if [ "$( fstyp ${bootdev} | grep hfs )" ]; then␊ |
␉echo "${bootdev} is a currently formatted as HFS"␊ |
␉efiformat="hfs"␊ |
fi␊ |
if [ "$( fstyp ${bootdev} | grep msdos )" ]; then␊ |
␉echo "${bootdev} is currently formatted as msdos"␊ |
␉efiformat="msdos"␊ |
␉#echo "Executing command: newfs_msdos -F 32 ${bootdev}"␊ |
␉#newfs_msdos -F 32 "${bootdev}"␊ |
fi ␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
diskupdate=false␊ |
␊ |
␊ |
checkdisksignature␊ |
checkdiskmicrocodetype␊ |
checkdiskmicrocode set␊ |
checkpartitionbootcode set␊ |
#checkpartitionactive␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Can we install the Chameleon bootloader files?:"␊ |
echo "**********************************************"␊ |
␊ |
if ${diskupdate}; then␊ |
␉echo "Diskupdate = true, so yes"␊ |
␉#---------------------------------------------------------------------␊ |
␉# Check bytes 438-446 of the GPTdiskProtectiveMBR for a Windows Disk Signature␊ |
|
␉#---------------------------------------------------------------------␊ |
␊ |
␉if [ ${disksignature} == "00000000" ]; then␊ |
␉␉echo "Executing command: fdisk440 -u -f ${diskloader} -y ${bootdisk}"␊ |
␉␉fdisk440 -u -f "${osxvolume}/${diskloader}" -y ${bootdisk}␊ |
␉else␊ |
␉␉#---------------------------------------------------------------------␊ |
␉␉# If it exists then Windows is also installed on the HDD and we need to write boot0hfs␊ |
␉␉#---------------------------------------------------------------------␊ |
␊ |
␉␉echo "Executing command: fdisk440 -u -f ${diskloaderdualboot} -y ${bootdisk}"␊ |
␉␉fdisk440 -u -f "${osxvolume}/${diskloaderdualboot}" -y ${bootdisk}␊ |
␉fi␊ |
else␊ |
␉echo "Diskupdate is false, so no stage 0 file was written"␊ |
fi␊ |
␊ |
␊ |
#echo "Executing command: dd if=${partitionloader} of=${bootrdev}"␊ |
#dd if="${osxvolume}/${partitionloader}" of=${bootrdev}␊ |
␊ |
echo "Prepare Stage 1 loader"␊ |
␊ |
echo "Executing command: dd if=${bootrdev} count=1 bs=512 of=/tmp/origbs"␊ |
dd if=${bootrdev} count=1 bs=512 of=/tmp/origbs␊ |
␊ |
if [ ${efiformat} = "hfs" ]; then␊ |
␉echo "Executing command: cp ${osxvolume}/${partitionloaderhfs} /tmp/newbs"␊ |
␉cp "${osxvolume}/${partitionloaderhfs}" /tmp/newbs␊ |
fi␊ |
␊ |
if [ ${efiformat} = "msdos" ]; then␊ |
␉echo "Executing command: cp ${osxvolume}/${partitionloaderfat} /tmp/newbs"␊ |
␉cp "${osxvolume}/${partitionloaderfat}" /tmp/newbs␊ |
fi␊ |
␊ |
echo "Executing command: dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc"␊ |
dd if=/tmp/origbs of=/tmp/newbs skip=3 seek=3 bs=1 count=87 conv=notrunc␊ |
␊ |
echo "Write Stage 1 loader"␊ |
␊ |
echo "Executing command: dd of=${bootrdev} count=1 bs=512 if=/tmp/newbs"␊ |
dd if=/tmp/newbs of=${bootrdev} count=1 bs=512␊ |
␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Set Active Partition ONLY if Windows is not installed:"␊ |
echo "*****************************************************"␊ |
␊ |
# If table is MBR make the correct slice active. If table is GPT make the first partition active (BadAxe compatibility).␊ |
#[ "${partitiontable}" = "GUID_partition_scheme" ] && bootslice=1␊ |
#if [[ "${partitiontable}" = "FDisk_partition_scheme" || "${partitiontable}" = "GUID_partition_scheme" ]]; then␊ |
#␉fdisk440 -e ${bootdisk} <<-MAKEACTIVE␊ |
#␉print␊ |
#␉flag ${bootslice}␊ |
#␉write␊ |
#␉y␊ |
#␉quit␊ |
#␉MAKEACTIVE␊ |
#fi␊ |
␊ |
if [ ${disksignature} == "00000000" ]; then␊ |
␉# echo "Windows is not installed so let's change the active partition"␊ |
␊ |
␉partitionactive=$( fdisk440 -d ${bootrdisk} | grep -n "*" | awk -F: '{print $1}')␊ |
␉echo "Current Active Partition: ${partitionactive}"␊ |
␊ |
␉if [ "${partitionactive}" = "${bootslice}" ]; then␊ |
␉␉echo "${bootvolume} is already flagged as active"␊ |
␉else␊ |
␉␉echo "${bootvolume} is not flagged as active, so let's do it."␊ |
␉␉# BadAxe requires EFI partition to be flagged active.␊ |
␉␉# but it doesn't' hurt to do it for any non-windows partition.␊ |
␉␉␊ |
␉␉fdisk440 -e ${bootrdisk} <<-MAKEACTIVE␊ |
␉␉print␊ |
␉␉flag ${bootslice}␊ |
␉␉write␊ |
␉␉y␊ |
␉␉quit␊ |
␉␉MAKEACTIVE␊ |
␉fi␊ |
else␊ |
␉echo "Windows is installed so we let that remain the active partition"␊ |
fi␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
#checkdiskmicrocode check␊ |
#checkdisksignature␊ |
#checkpartitionbootcode check␊ |
#checkpartitionactive␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Mount EFI partition:"␊ |
echo "********************"␊ |
if [ ${efiformat} = "hfs" ]; then␊ |
␉[ -d "${bootvolume}" ] || mkdir -p "${bootvolume}"␊ |
␉echo "Executing command: mount_hfs -u 0 -g 0 ${bootdev} ${bootvolume}"␊ |
␉mount_hfs -u 0 -g 0 "${bootdev}" "${bootvolume}"␊ |
else␊ |
␉[ -d "${bootvolume}" ] || mkdir -p "${bootvolume}"␊ |
␉echo "Executing command: mount_msdos -u 0 -g 0 ${bootdev} ${bootvolume}"␊ |
␉mount_msdos -u 0 -g 0 "${bootdev}" "${bootvolume}"␊ |
fi␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
␊ |
echo "==============================================="␊ |
echo "Write Stage 2 loader"␊ |
echo "********************"␊ |
␊ |
echo "Executing command: cp ${osxvolume}${filesystemloader} ${bootvolume}/boot"␊ |
cp "${osxvolume}${filesystemloader}" "${bootvolume}/boot"␊ |
echo "boot written"␊ |
␊ |
echo "-----------------------------------------------"␊ |
echo ""␊ |
echo ""␊ |
␊ |
# setup link for extras␊ |
#echo "Executing command: ln -s /Volumes/${bootervolumename} ${2}/.Chameleon"␊ |
#ln -s "/Volumes/${bootervolumename}" "${2}/.Chameleon" ␊ |
# setup link for extras␊ |
␊ |
exit |