This weekend, I finally decided to try to set up my MacBook Pro to boot into OS X, Windows XP, and Ubuntu. I ran into a few problems so I’d like to share what I did to make it all work. A lot of what I did was driven by other people’s wiki articles and blog posts, particularly this excellent blog about manually editing partitions. Without further adieu, I will describe my setup from start to finish.
Initial setup
I started out with a working install of Mac OS X 10.6 (Snow Leopard) and Windows XP, which I had previously installed using Boot Camp. This was on a 320 GB hard drive. Both of these operating systems were working perfectly. I had started with a full OS X install and then used Boot Camp to install Windows XP. My partition layout looked like this:
- GPT:
- EFI System (FAT) — 200 MB
- Mac OS X (HFS+) — 246 GB
- Windows XP (NTFS) — 51 GB
- MBR:
- EFI Protective partition — about 200 MB
- Mac OS X (HFS+) — 246 GB
- Windows XP (NTFS) — 51 GB [active]
- Unused
As you may know, the GPT and MBR partition tables are set up in a “hybrid” approach with Boot Camp that allows older operating systems like Windows XP to still access up to three partitions despite lacking support for GPT. The first EFI Protective partition has to be there, so that only leaves three free slots to put partitions accessible to non-GPT-compatible operating systems such as Windows XP.
I also had rEFIt installed, but it wasn’t really necessary at the time since I was only booting Mac OS X and Windows. I knew I’d need it for booting Ubuntu though, so it’s best to make sure it’s installed and working before continuing on.
Preparation
I read all about setting up a Mac for triple-booting, and it seemed pretty clear that Windows likes to be the last partition on the hard drive. I don’t know if that’s true, but conveniently, Windows was already at the end of the disk. I just needed to shrink my Mac OS X partition to make room for extra partitions in between. So I used Disk Utility (well, tried to use Disk Utility) to shrink my OS X partition to a size of about 177 GB after clearing some space. Disk Utility took forever and finally complained saying that it was having trouble shrinking the disk. I don’t know for sure if this fixed it or not, but I used dd in the Terminal to fill the rest of my Mac OS X partition with a file full of zeros:
dd if=/dev/zero of=zerofile
This caused warnings which I ignored until dd quit due to the disk being full. Then I removed the file:
rm zerofile
This still didn’t help Disk Utility succeed though. Finally I rebooted into single user mode, ran “fsck -y” to ensure the disk had no errors (and indeed it was fine so I don’t think this did anything to help), and then booted into the full OS X. After that, Disk Utility was able to successfully resize my OS X partition. Not sure exactly what fixed it, but the zero file couldn’t have hurt. It’s also possible that simply rebooting allowed a few files to be moved around that otherwise weren’t able to be moved. Dunno, but anyway, then I was ready to continue with about 70 GB of space remaining between my OS X and Windows XP partitions.
Installing Ubuntu
I would probably recommend creating an Ubuntu 13.04 boot CD, but I was actually able to boot from a USB drive that I manually created. Essentially, older Intel Macs (mine is a 17″ MacBook Pro with Core Duo processor) will not boot from a live USB disk unless you format the whole disk as FAT32 instead of making a partition table with a single FAT32 partition. So I basically manually created the live USB image with a process similar to what was described in this blog post–formatting my full USB drive as FAT32 with no partition table, copying everything over, renaming isolinux to syslinux, and then running syslinux. This helped me boot from a USB drive. It’s not necessary if you simply burn a CD, and I think newer Intel Macs are more compatible with normal USB boot disks.
After doing this, rEFIt was able to boot the USB drive. So I booted from it and installed Ubuntu 13.04. The live USB drive took forever to boot and everything was extremely slow while it was booted, but it seemed to work OK. I told Ubuntu that I wanted to customize my partition layout rather than letting it set things up automatically. I created a 67-ish GB root partition (mounted as “/”) and another partition for swap. I saw many guides that said you should not create a swap partition (instead, create a swap file on the Linux root filesystem partition), but I chose to ignore that advice, which may have been part of my problem. Not sure…
For bootloader installation, I told it to install onto the newly-created Linux root filesystem partition–NOT the full hard drive, but the partition. This caused the installer to warn me that this is not a good idea, but it seems to be the correct way to get rEFIt to detect it.
Partition layout after install
After the install completed, my partition tables looked like this:
- GPT:
- EFI System (FAT) — 200 MB
- Mac OS X (HFS+) — 177 GB
- Windows XP (NTFS) — 51 GB
- Linux — 67 GB (but physically this is directly after the Mac OS X partition)
- Linux Swap — 2.7 GB (but physically this is directly after the Linux root filesystem partition and before the Windows XP partition)
- MBR:
- EFI Protective partition — about 200 MB
- Mac OS X (HFS+) — 177 GB
- Windows XP (NTFS) — 51 GB [active]
- Linux — 67 GB (but physically this is directly after the Mac OS X partition)
Of course, the hybrid MBR left off the swap partition because there was no room for it. That’s OK, though, because Windows doesn’t need to access my Linux swap partition. What I was more concerned about was the physical ordering of the partitions. When I talk about the partitions being physically in a different order, what I mean is this: I’m showing you the list of partitions in the order they are listed in the partition table. But the order in the partition table does not match their actual ordering on the disk from start to end. This was kind of a weird situation because my partition table was out of order. The Windows XP partition came before the Linux partitions in the ordering even though it was physically at the end of the disk past the two Linux partitions.
I don’t think this is usually a big deal, but I’m pretty sure Windows does not like this setup or something. I left the partition layout as listed above and crossed my fingers, but…
The problems began
This is where I started having issues. After installing Ubuntu, I was able to successfully boot into OS X and Ubuntu, but Windows would no longer boot. It would immediately display the following error:
Windows could not start because the following file is missing or corrupt: <Windows root>\system32\hal.dll Please re-install a copy of the above file.
Hmm. Naturally I started Googling and the results looked promising. This happens because the Windows XP bootloader (NTLDR) is looking on the wrong partition for the Windows install. It happens commonly with Boot Camp when partitions get moved around, and the fix is usually to edit the C:\boot.ini file (from another Windows computer, or from your Linux install) to tell it the correct partition to look on. Here was the content of my boot.ini file:
[boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(3)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(3)\WINDOWS="Microsoft Windows XP Home Edition" /noexecute=optin /fastdetect
The partitions you would put into this file start with the number 1 (so there’s no such thing as partition 0; the first partition is partition 1). Typically when this problem occurs, it’s because extra partitions have been inserted in between and the number needs to be raised. For example, if the Windows partition is now the fourth MBR partition, the two places where it says partition(3) should be changed to say partition(4). Unfortunately, in this case, the file seemed correct because my Windows partition was still partition 3. So maybe this is what people are talking about when they say the Windows partition has to come last…
Nevertheless, I tried playing with the partition number in boot.ini. I tried 4 (thinking maybe it was referring to physical ordering on the disk), but that didn’t work. I should have known that the number 5 wouldn’t work since the MBR only had 4 partitions, but I tried it anyway and obviously it didn’t work either. Here’s where things got weird: I tried changing it to 2, and that seemed to resolve the error! Where did the partition number 2 come from? Partition 2 is the Mac OS X partition. It makes absolutely no sense at all. Even if somehow it was zero-indexed, then it shouldn’t have worked originally before I installed Linux. This was extremely puzzling.
Anyway, when I changed the partition number to 2, I thought I had fixed the problem because the Windows XP startup screen came up, but clearly it didn’t work. All of a sudden the screen flashed blue really quickly and the computer rebooted. Uh oh, a blue screen of death! The computer was rebooting so quickly that I couldn’t read it. I used my phone to record a movie of it and was able to figure out what the blue screen said:
A problem has been detected and Windows has been shut down to prevent damage to your computer. PROCESS1_INITIALIZATION_FAILED If this is the first time you've seen this Stop error screen, restart your computer. If this screen appears again, follow these steps: ...
No matter how many times I tried to boot Windows, this error always appeared. I headed back to Google and the results I found really weirded me out. This error can also appear when boot.ini contains the wrong partition number. Clearly, Windows was upset because boot.ini was now pointing at partition 2 when it was supposed to be pointing to partition 3. But why was NTLDR only working when I told it to use partition 2? I don’t have an explanation. This still has me puzzled. If any readers can explain why NTLDR only worked when boot.ini contained partition 2 in this situation, I’d love to hear why in the comments below. Anyway, I started thinking about a better way to solve this problem.
Now what?
My first idea: manually fix the hybrid MBR so that the Linux partition is #3 and the Windows partition is #4. After all, other results indicated that the Windows partition needs to be the last partition, and ideally Windows XP shouldn’t care about the GPT at all. I used fdisk in Mac OS X to edit the MBR so that the third partition and fourth partition’s entries were swapped. To manually edit the partition table, I used the instructions provided in the first blog post I linked at the beginning of this article. I also changed it so that partition #4 was now marked active. So now my MBR looked like this (the GPT was unchanged):
- EFI Protective partition — about 200 MB
- Mac OS X (HFS+) — 177 GB
- Linux — 67 GB
- Windows XP (NTFS) — 51 GB [active]
This also didn’t work. I can’t exactly remember what behavior I saw, but I believe this caused NTLDR to fail to boot until I entered partition #3 into boot.ini, and it again gave the PROCESS1_INITIALIZATION_FAILED blue screen of death (probably because Windows was expecting boot.ini to refer to partition #4). So again, there was some kind of weird inconsistency between the partition numbering used by NTLDR and Windows.
I decided to revert back to what I had before to make sure Windows wasn’t damaged. To do this, I simply swapped the Linux and Windows XP partitions back the way they were before in the hybrid MBR, and then removed the Linux entry from the MBR, leaving the following MBR setup:
- EFI Protective partition — about 200 MB
- Mac OS X (HFS+) — 177 GB
- Windows XP (NTFS) — 51 GB [active]
- Unused
Once again, I didn’t touch the GPT at all. I only modified the MBR. This actually made Windows boot correctly (with boot.ini set for partition #3). This reassured me that the Windows install itself was not hosed in any way. Unfortunately, it broke Ubuntu — GRUB came up, but choosing the Ubuntu option caused Windows to boot instead. So there’s something about having that fourth entry populated in the MBR that screws up NTLDR and makes it number the partitions incorrectly, I guess. I still don’t understand it.
Rearranging the GPT
OK, so I figured that something else was going on. I finally decided to reorder the GPT instead. I installed GPT fdisk in Mac OS X to try rearranging the GPT to see if that would make a difference at all. I tried to put the GPT partitions into the same order that I wanted the MBR partitions to be in earlier. To accomplish this, there is a “transpose” command for swapping two partition entries in the GPT–see the “t” command in the expert menu. After reordering the GPT, I also used GPT fdisk to create a new hybrid MBR to match. There’s also a command for recreating the hybrid MBR–see the “h” command in the recovery and transformation menu. NOTE: I made sure to back up the first sectors of my hard drive just in case I screwed something up while doing this. I didn’t do this with any critical data that wasn’t backed up either — it would have been possible to really screw something up.
After using GPT fdisk to move the partitions around and regenerate the hybrid MBR, here’s how the partition tables looked:
- GPT:
- EFI System (FAT) — 200 MB
- Mac OS X (HFS+) — 177 GB
- Linux — 67 GB
- Windows XP (NTFS) — 51 GB
- Linux Swap — 2.7 GB (but physically this is directly after the Linux root filesystem partition and before the Windows XP partition)
- MBR:
- EFI Protective partition — about 200 MB
- Mac OS X (HFS+) — 177 GB
- Linux — 67 GB
- Windows XP (NTFS) — 51 GB [active]
As you can see, all the partitions with the exception of the linux swap partition are in their physical order on disk, the GPT and MBR’s first four entries match each other, and Windows XP is on partition #4.
Success (sort of)
After making this change to the partitioning, Windows booted correctly (with boot.ini set for partition #4 as expected). Ubuntu would no longer boot because GRUB was looking on the wrong GPT partition after the GPT partition number of the Linux partition changed. GRUB dropped me into a “grub rescue>” prompt. This was fixable by manually telling GRUB to boot into the correct partition (see the excellent Ubuntu wiki troubleshooting instructions):
ls
This gave me a list of available partitions. Then I kept trying different partitions until I found the partition with /boot on it:
ls (hd0,gpt4)/boot/ ls (hd0,gpt3)/boot/
I believe gpt3 was the correct one–it didn’t error out, and showed my kernel and a few other files. Thus I continued as described in the Ubuntu wiki:
set prefix=(hd0,gpt3)/boot/grub set root=(hd0,gpt3) insmod normal normal
After booting into Ubuntu, I reinstalled GRUB. I checked to see which partition was the mounted root filesystem by typing “mount” into a terminal (it was /dev/sda3):
sudo update-grub sudo grub-install -f /dev/sda3
I had to use -f because GRUB didn’t want to install itself onto a partition unless I proved to it that I knew what I was doing.
Finally, after verifying that everything was working, I decided to reconfigure GRUB as well, to ensure that any automatic updates in the future would be installed to the correct partition:
sudo dpkg-reconfigure grub-pc
I entered the defaults for all of the choices until I got to the point where it asked what devices to install grub to. I picked /dev/sda3 (and pressed space to mark it as a partition to use). I actually didn’t do this step the first time I did this whole thing, but it’s an important step because otherwise, the next GRUB update will install to the wrong partition. In my case, it installed onto the Windows partition and broke Windows when I updated to Ubuntu 13.10. So definitely make sure you do this reconfigure command to ensure that Ubuntu is aware of which partition it should be installing GRUB to. I believe running this command will actually do the grub-install command automatically as well, so you may not have to do it manually like I did above.
All done
Finally, the madness was over. At this point Mac OS X, Windows, and Ubuntu all booted correctly from rEFIt. The beauty of this approach is I can indeed have a separate swap partition. Can anyone explain why things didn’t work until I rearranged the GPT and recreated the hybrid MBR? I don’t think my original MBR was damaged; it just seems like NTLDR was looking at the wrong partition. Does NTLDR with Windows XP somehow look at the GPT and get confused? I don’t think Windows XP 32-bit looks at the GPT at all, so I would have thought rearranging the MBR and leaving the GPT would have fixed the issue, but it didn’t seem to work until I fixed the GPT too. I dunno…
In hindsight, it may have been smart to create another partition in Disk Utility to fill the empty space after I shrank my OS X partition. I’m guessing that would have correctly shifted the Windows partition into position #4 instead of having to fix it manually. I plan on redoing this setup on another computer in the future to see if I can reproduce this weird problem to get a better handle on what exactly it takes to make it work.
I hope this helps someone out there struggling with a triple-boot setup…
Update: I found a post on Apple’s boot-dev mailing list that indicates that my suspicion about NTLDR looking at the wrong partition was probably correct. It sounds like NTLDR looks at the GPT but Windows XP itself only looks at the MBR. I still don’t think it explains why I had problems with the original partitioning scheme, though; after originally adding the Linux partitions, the Windows partition was partition #3 in both the MBR and the GPT. My guess is that NTLDR has some weird, broken rules with partition ordering when GPT is involved and perhaps it’s solved by making sure the GPT and MBR’s ordering match up, as well as making sure the Windows partition is partition #4. That’s the best I can come up with. I don’t know for sure, but at least I know the setup I have now works!
Update 2: I just tried this process on a 20″ iMac (Early 2008) and had similar results. Until the GPT’s partition ordering matched the hybrid MBR, Windows XP would not boot. Unfortunately the iMac had problems in Ubuntu 13.04 after the login screen, so I don’t plan on using it for a triple-boot setup. But I can confirm that Windows XP’s bootloader surprisingly cares about the GPT layout.
very useful, thanx.
just one more question, how are you sharing data between partition? is this necessary to you or you’re doing different work on different platforms?
would you recommend a “shared data” partition? In this case which filesystem would you recommend?
thank you
Thanks, I hope it helps! BTW, if you’re using a version newer than 10.6, you may run into trouble because of the recovery partition that OS X 10.7 and newer create. You might have to reorder the partitions so that the recovery partition is not one of the first four partitions. Not sure exactly.
I’m not really sure for shared data. You could probably use the OS X partition. I think Linux and Windows (with Boot Camp installed) can both read and write HFS+ partitions, so that might be the easiest way to share data between all three operating systems.
I’m trying this with 10.9+windows7(or 8, still have to choose this)+linux(probably ubuntu). I’m searching around and found other approaches with chameleon or chimera bootloader
I found utilities and drivers for about all the win\osx\linux stack to interact with all ntfs\hfs+\ext4 filesystems in rw so I’m not worried that’s not possible, I’m just wondering how other “triplebooters” are facing the problem of redundant data.
in my case, I’m programming on all 3 OSs and using mainly the same codebase on each OS. I’m thinking of putting this codebase in a shared folder (or partition) accessible from all platforms but I’m trying to understand if there’s any major drawback ( line endings, .DS_store\.thumbs files, etc ) that makes this approach not viable.
any suggestion?
You probably don’t need to do any of the special partition reordering things I talked about in this blog post with your setup — I believe that 64-bit Windows 7/8 should work OK since they directly support EFI and booting from GPT disks, so they shouldn’t have any of the weird problems I saw with XP.
I don’t really have a great suggestion for using this mechanism to share a single codebase across all three operating systems. I honestly don’t really do any development on my triple boot system. If it were me personally, I’d probably use an external version control server and keep separate checkouts on all three partitions. I agree the invisible files created by Windows and OS X might be annoying to see if you share everything…although version control systems would also put invisible folders (.git, .svn, etc.) in your directories.
Hi,
I have a related question (if anyone could help):
How do you delete files within the ‘protected’ EFI partition?
I have a nasty “Windows boot.ini” that I need to delete to then try again….
Anything is appreciated! Thanks!!!!
Hi Dough
Thanks for sharing the (bumpy) path you walked and your working solution at the end.
In in the process of fixing my first attempt to have a triple boot with Win XP (I need it for older hardware that comes with Win XP drivers only, unluckily), and I’ve spent already 3 days installing OS’s!. A lot of trial & error until I’ve ended into a similar solution to yours.
In short:
* My current attempt involves moving the windows ntfs partition to after GNU/Linux (Ubuntu 12.04 in this case).
* And I also liked
** having “/home” in a different partition than “/” (for easier reinstall keeping all user settings, etc),
** and having some swap partition on its own (to ease suspending to RAM).
I’ll see if I can manage to have /home and swap after the windows XP ntfs partition. Windows shouldn’t bother those partitions, since it doesn’t use them at all.
Thanks, very useful article, very well written :). I just got to the same conclusion as you – the number in GPT must match the number in hybridMBR, otherwise you will end up with hal.dll madness…
Z.