Introduction
This posting documents how I configured triple boot environment of Ubuntu 9.10 karmic, Mac OS X 10.6 and Windows 7 on one of my machines. All operating systems are installed on a single physical disk. Grub 2[1] boot loader installed by Ubuntu will be used as the primary boot loader. Grub will be then used to boot Chameleon[2] boot loader which boots Mac OS X. Grub boots Ubuntu and Windows directly.
Partitioning the disk
Partitioning the disk causes headache and requires some tweaking as we have to install both GUID Partition Table[3] and Master Boot Record Partition Table[4] on the same disk. Mac OS X only supports system disks with GPT. But Windows doesn’t support booting from a disk with GPT[5]. Ubuntu is happy to boot from disks paritioned using both GPT and MBR. Thus we have to create hybrid GPT/MBR boot record[6].
We’re going to do the initial partitioning of the system disk using Mac OS X installer. Follow the instructions in the posting Create Mac OS X 10.6 Snow Leopard USB installation media for Hackintosh and create bootable Mac OS X installer USB media.
Next we have to decide the partition table layout. When installing Grub 2 on a disk with GPT, it’s recommended to have BIOS Boot Partition[7],[8]. With the hybrid partition table in place, you’re limited to only 4 partitions that are available to Windows. And two of these partitions are reserved (EFI Partition and BIOS Boot Partition) so you only have 2 primary partitions to configure at your will. Also it’ll be difficult to work with the partitioning after we’ve finished with the installations and gotten everything to work so it’s better to do good initial planning.
Ubuntu 9.10 karmic and later install Grub 2 that is capable of
handling LVM. Since we’re going to install Ubuntu on logical
volume(s), there’s not need for a separate partition for
/boot file system. That’s great!
I partitioned my 600GB disk as follows:
- Partition 1: 200MB HFS+ volume labeled
EFI. This is created automatically when partitioning the disk with Mac OS Xdiskutil(8)[9] tool. Chameleon boot loader code and support files are also installed on this volume. This way there’s no need to do any customization to the Mac OS X volume described below. - Partition 2: 2MB volume for the BIOS Boot Partition. Used by Grub.
- Partition 3: 150GB NTFS volume for Windows.
- Partition 4: 50GB Physical volume for volume group managed by LVM. The volume group will house the Ubuntu installation.
- Partition 5: 100GB Mac OS X system volume labeled
Hackintosh HDfor the operating system, applications and user home directories. - Partition 6: ~300GB HFS+ volume labeled
Videofor video archive and scratch space used during editing of home videos.
To partition the disk boot Mac OS X installer and launch
Terminal.app from the Utilities menu. First
identify the system disk.
-bash-3.2# diskutil list
In my system the system disk is /dev/disk7. Then I
partitioned the disk using the following command.
-bash-3.2# diskutil partitionDisk /dev/disk7 GPT \
"MS-DOS FAT32" %noformat% 2M \
"MS-DOS FAT32" %noformat% 150G \
"MS-DOS FAT32" %noformat% 50G \
"Journaled HFS+" "Hackintosh HD" 100G \
"Journaled HFS+" Video 0b
I marked the Windows, Linux and BIOS boot partitions temporarily as FAT32 so that the space gets allocated for these partitions. The Windows partition will be formatted as NTFS when installing Windows 7, the Linux partition will be added to the volume group when installing Ubuntu and Grub installer will use the BIOS boot partition.
Installing Chameleon boot loader
The empty, just partitioned hard disk is not bootable and won’t
be even after installing Mac OS X in the next step. But we can copy
Chameleon boot loader and its configuration from the Mac OS X USB
installer to the system disk. See
my guide for more details about Chameleon. These steps assume
that the Mac OS X installer was created like documented in that
posting. While still in the Mac OS X installer with
Terminal.app running, execute the following
commands.
-
Create HFS+ file system on the EFI volume and mount it.
-bash-3.2# newfs_hfs -v EFI /dev/disk7s1 -bash-3.2# mkdir /Volumes/EFI -bash-3.2# mount_hfs /dev/disk7s1 /Volumes/EFI -
Mark the EFI file system so that fseventsd doesn’t keep any logs there.
-bash-3.2# mkdir /Volumes/EFI/.fseventsd -bash-3.2# touch /Volumes/EFI/.fseventsd/no_log -bash-3.2# chmod -R g-rwx,o-rwx /Volumes/EFI/.fseventsd -bash-3.2# chown -R root:admin /Volumes/EFI/.fseventsd -
Copy the Chameleon boot loader binaries to the root of the EFI volume. You really need the
bootfile, which is the last stage of Chameleon boot system and contains bulk of the Chameleon code, but it’s a good idea to have the images of the first stages at hand, too.-bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot /Volumes/EFI -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot0 /Volumes/EFI -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot1h /Volumes/EFI -
Copy Chameleon support file directory
Extrato the EFI volume.-bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/Extra /Volumes/EFI/Extra -
Unmount the EFI volume.
-bash-3.2# umount /dev/disk7s1 -bash-3.2# rmdir /Volumes/EFI -
Eject the system disk so that you can write to the block device file in the next step.
-bash-3.2# diskutil eject /dev/disk7 -
Now you can copy the Chameleon initial boot code from the installer file system to the Master Boot Record at the beginning of the system disk.
-bash-3.2# dd if=/Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot0 of=/dev/disk7 bs=440 count=1 -
Then copy the Chameleon 2nd stage boot code from the installer file system to the beginning of the EFI partition.
-bash-3.2# dd if=/Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot1h of=/dev/disk7s1 -
Bootloader installation is now ready. Mount the Mac OS X volume so you can install Mac OS X onto it.
-bash-3.2# diskutil mount /dev/disk7s5 -
Finally, quit
Terminal.app.
Installing Mac OS X 10.6 Snow Leopard
Go ahead and install Mac OS X normally on the Mac OS X volume
(Hackintosh HD). After the installation is finished,
the machine should boot to Mac OS X as we installed the Chameleon
boot loader to the Master Boot Record and support files to the EFI
partition in the previous steps. It’s a good idea to create backups
of the Master Boot Record of the system disk at this stage so you
can revert back if needed. You can use e.g.
dd(1)[10]
in Mac OS X installer shell.
-bash-3.2# dd if=/dev/disk7 of=/Volumes/BackupVolume/mbr-backup bs=512 count=1
Installing Windows 7
When the system disk was partitioned above with
diskutil(8)[9],
it also created the hybrid GUID/MBR partition table. You can now
boot Windows 7 installer and format the partition dedicated to
Windows as NTFS. Proceed to install Windows on this partition.
After Windows is installed, the machine now boots Windows as the
Windows installer replaced Chameleon boot code in the Master Boot
Record with its own boot code. No need to worry, we’ll get Mac OS X
back after installing Ubuntu and configuring Grub.
Installing Ubuntu 9.10 karmic
Use Ubuntu alternate installer[11].
Boot the installer and proceed to the disk partitioning step.
Choose manual partitioning and create a volume group to the
partition dedicated to Ubuntu, create required volumes and install
Ubuntu there. When the installer prompts for boot loader device
installation, don’t answer yet but switch to the console
(Alt-F2). We need to activate the BIOS Boot Partition
first. In the following setup /dev/sda is the physical
system disk.
-
Mount the special file systems at the target file system.
~ # mount -o bind /dev /target/dev ~ # mount -o bind /sys /target/sys ~ # mount -o bind /proc /target/proc -
Enable BIOS Boot Partition using
parted(1)[12].~ # chroot /target parted /dev/sda set 2 bios_grub on -
Unmount the special file systems at the target file system.
~ # umount /target/dev ~ # umount /target/sys ~ # umount /target/proc
Now switch back to the installer virtual console
(Alt-F1) and input the system disk block device name
/dev/sda and finish with Ubuntu installation.
Restoring hybrid partition table
After installing Ubuntu, you should be able to boot it using
Grub. However, Ubuntu installer and parted(1) have
destroyed the hybrid GPT/MBR partition table. But we can fix that
using the gptsync(1) tool which is part of the
rEFIt[13].
gptsync package is available for Ubuntu[14],
but unfortunately the version in karmic is too old to
support BIOS Boot Partitions[15].
This has been fixed in the version 0.13-4 of the package.
Until there’s a working version of gptsync package in
Ubuntu, you can use the package from Debian[16].
When you have a version of gptsync(1) installed which
supports BIOS Boot Partitions, go ahead and re-create the hybrid
partition table.
~$ sudo gptsync /dev/sda
Updating Grub boot menu
Ubuntu installer should detect the Windows 7 installation and create a Grub menu entry for it. It’ll also detect the Mac OS X installation and create menu entry for that, too. However, that is no good to us since it uses Grub’s native Mach kernel loading facilities[17] but we want to use Chameleon to boot Mac OS X.
So let’s create a custom menu entry that will boot Chameleon. Save the following script as /etc/grub.d/99_local_chameleon and set it executable.
#!/bin/sh cat <<END_OF_MENU_ENTRY menuentry "Mac OS X via Chameleon" { insmod hfsplus set root=(hd0,1) multiboot /boot } END_OF_MENU_ENTRY
~$ sudo chmod 755 /etc/grub.d/99_local_chameleon
And update the Grub configuration.
~$ sudo update-grub
Now you should have Grub menu from which you can choose whether to boot Ubuntu, Mac OS X or Windows.
Fixing Windows
Unfortunately, partition changes related to Ubuntu installation
breaks Windows on my machine. When trying to boot Windows, I get
Windows Boot Manager error screen with status
0xc00000e. To fix this, boot to Windows Recovery
Environment and start Command Prompt. With Windows 7
retail DVD in hand, boot it, choose your language and locale
settings and choose Repair your computer. If the Recovery
Environment asks Do you want to apply repairs and restart your
computer, choose No. Choose Use recovery tools
that can help fix problems starting Windows and then clck
Command Prompt. In the Command Prompt find the drive that
contains the Windows installation. Most likely it’s
C:. Run the following commands to repair Windows Boot
Catalog.
bcdedit /set {default} device partition=c:
bcdedit /set {default} osdevice partition=c:
bcdedit /set {bootmgr} device partition=c:
It should now be possible to boot Windows from the Grub boot menu.