Index: branches/blackosx/trunk/package/Scripts/EFI/postinstall =================================================================== --- branches/blackosx/trunk/package/Scripts/EFI/postinstall (revision 0) +++ branches/blackosx/trunk/package/Scripts/EFI/postinstall (revision 201) @@ -0,0 +1,450 @@ +#!/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 thereีs no Windows disk signature then we can write boot0 + #--------------------------------------------------------------------- + + 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 \ No newline at end of file Property changes on: branches/blackosx/trunk/package/Scripts/EFI/postinstall ___________________________________________________________________ Added: svn:executable + *