Windows – Hibernate between OS X and Bootcamp Win 7

boot-camphibernatemacosmulti-bootwindows 7

Is it possible to use the true hibernate system functionalities of Win 7 and OS X to create a kind of instant switching between the two? Imagine this when reading/writing the sleep images to a quick SATA-3 SSD.

Hibernate-corruption-fix: If this is made possible, make sure that your different partitions are not write-enabled from eachother. (e.g. make it so that Boot Camp Windows 7 cannot write to OS X partition and vice versa). This safety measure should make it impossible for your different systems to corrupt eachother when one is suspended into hibernation.

Edit: I realized that I'm not sure that this is how partitions work on a disk. The hibernated OS X kernel could have references to blocks on the disk which it will continue to write to when it is woken up again. Are disk blocks like these contained within a partition or are they assigned to a partition after they have been written on? Is it different on HDD and SSD? Does this affect the above hibernate-corruption-fix?

Ok let's move on:

Windows 7 already has an option "Hibernate" which allows you to boot back to your OS X partition, but OS X does not exactly offer the same.

With OS X it is possible to hibernate by changing the hibernatemode system variable.

Pre OS X 10.7

sudo pmset -a hibernatemode 2

OS X 10.7

sudo pmset -a hibernatemode 25

This makes your Mac go into hibernate when you put it to sleep.
You can put it to sleep with:

sudo shutdown -s now

Ok, so far so good. So we can put both Windows 7 and OS X Lion into hibernation at will. But wait! There's more problems up ahead.

When you put OS X into hibernate it will automatically boot back into OS X when you power your Mac on again. This makes it impossible for us to use it for "hotswitching" between partitions.

Possible fixes:
If you install rEFIt without rEFItBlesser you will get the rEFIt boot menu after OS X hibernation. On OS X 10.7 Lion however, this does not fully work, instead you get a black screen and have to hard shutdown your Mac. But hey! At least it interrupts the automatic OS X boot, right? Maybe it can be tweaked further from there.

As mentioned on earlier OS X:s the rEFIt boot menu actually does come up after hibernation shutdown + power on. This allows you to e.g. boot your Boot Camp Windows 7 partition instead.
There are problems here as well though. Apparently the OS X partition loses its hibernation flag if you follow this method, which means that the next time you boot into OS X, it will not return from its hibernation state. Instead it will do a clean startup. Why is this?
Does OS X look for the existence of a sleep image to determine wether to wake up from hibernation or to do a clean start or does it have some kind of system variable/flag set?

Summary

When Win 7 goes into hibernate it shuts down completely and you can then boot into OS X on startup. On OS X however, hibernate forces you to wake up into OS X. Can you hack this so that you're allowed to select boot partition after OS X hibernates and still be able to return later to OS X and wake it up from its hibernate?

Let's see what we collectively can come up with!

Best Answer

It is not possible to do this the way you are thinking. The problem lies in the tight integration of Apple's firmware and OS X. OS X and the firmware work with each other to determine the sleep state of the computer.

When Windows hibernates, it dumps the contents of RAM to C:\Hiberfil.sys and sets a flag in the registry that the machine is hibernated. When you first boot a Windows machine, the boot sector code loads the BCD file, which loads that portion of the registry very early in the boot process and sees that the system is hibernated. After performing a basic sanity check, it loads hiberfil.sys back into memory. The important thing here is that all all of this is contained within the filesystem. This is why you can freely boot to OS X, then boot again back to Windows and it will continue to resume from the hibernation file.

The same is not true of OS X. When OS X hibernates, it dumps the contents of RAM to /var/vm/sleepimage the same way Windows does. But it saves the hibernation flag in the PRAM, not the filesystem (the setting is called IORegistryCurrentSleepMode if you're interested). When you turn a Mac back on, the values in PRAM are read before an attempt is even made to boot to the OS. If the flag indicates that the system is hibernated, the first thing it does is flip it back to a normal status. The firmware then immediately boots the system and ignores the Startup Disk preference and any attempts to Option+boot. You don't even get a startup chime. On a Mac, the firmware contains all the logic needed to inspect the filesystem and boot the OS. It does not need boot code the way Windows does.

When you throw rEFIt into the mix, it inserts itself into the process. It replaces the normal /System/Library/CoreServices/boot.efi (which is OS X's boot loader), with its own boot loader file. This is where things get fuzzy for me because this is all Apple proprietary stuff, but the bottom line is that when the firmware is booting OS X, it passes whatever arguments needed to load /var/vm/sleepimage instead of the normal Darwin kernel. rEFIt does not do this properly with Lion and later. But regardless of whether it's an older version of OS X or a newer one, the firmware has already flipped the hibernation bit before rEFIt even loads. This is why resuming OS X from hibernate is no longer possible after the first power-on.

Related Question