Hibernate on your non-brandnew Mac

An interesting feature of the newish "hires" (Double-Layer SD) powerbooks announced in Oct 2005 is "Safe Sleep" support. As well as keeping the ram active (normal sleep), Safe Sleep writes the active memory to a file on disk so that even if the battery goes flat or is removed, the system state is preserved ("hibernate"). As long as the laptop has retained power when sleeping, it will wake up normally.

If you don't care about how it works, click here to see how to enable it.

This feature is very much a software feature, not hardware — Linux actually calls it "Software Suspend". When 10.4.3 came out a few weeks after the PowerBooks, it seemed likely to have some new features...

All testing was done on an iBook 1 GHz with 1.25 gigs ram, running 10.4.3. I assume other macs should work, though maybe only if kextstat shows the AppleKauaiATA driver...

What makes it tick?

First stop for 10.4.3 changes is the Darwin sourcecode. In the xnu package (the kernel itself), grepping for hibernate there's a few files in the xnu-792.6.22/iokit/Kernel/ dir. The most prominent is IOHibernateIO.cpp .

After a few failed attempts at getting it to hibernate to a file, it seemed that the ATA driver was missing support for IOPolledInterface. Eventually, I figured that the AppleKauaiATA driver actually checks for a "has-safe-sleep" property of the "ata" device, and only enables the polled interface if that is set. (This was confirmed from looking at ioreg -l -w 0 output from a new PowerBook 15").

Grepping for "has-safe-sleep" in /System/Library/Extensions , the AppleMacRISC2PE "Platform Expert" looks to be a likely candidate. In there, we find a check:

(from MacRISC2.cpp): bool MacRISC2PE::platformAdjustService(IOService *service) { bool result; if (IODTMatchNubWithKeys(service, "kauai-ata")) { IORegistryEntry *devicetreeRegEntry; OSData *tmpData; devicetreeRegEntry = fromPath("/", gIODTPlane); tmpData = OSDynamicCast(OSData, devicetreeRegEntry->getProperty("has-safe-sleep")); if (tmpData != 0) service->setProperty("has-safe-sleep", (void *) 0, (unsigned int) 0); }

In the new PowerBook ioreg output, there is indeed a root level item "has-safe-sleep".

Faking it

First up, remember that this isn't supported by Apple. There may be reasons why it's been supported as a "hardware" feature only in new machines that I don't know about — be cautious. It seems to work fine on the majority of G4s, except 12" 867MHz PowerBooks.

In order to create the "has-safe-sleep" property, we need to run something in Open Firmware at boot. This is what nvramrc is good for, as used by other great hacks such as the iBook dual-head hack (see down the bottom of that page).

The basic openfirmware command is

" /" select-dev

" something" encode-string " has-safe-sleep" property

meaning "Create a 'has-safe-sleep'='something' property in / of the device-tree".

I've made a few scripts to set the relevant variables. Just extract the scripts and run them from a terminal.

Since the hibernate hack will interfere with the iBook dual-head hack I've included a variant which'll set that as well - don't use that script if you're not already using that hack, it can be hazardous on some machines. My version does infinitely less checking than the original.

Wom....

The remaining step is to enable hibernate mode. Make sure you have at least as much free disk space as physical memory + 750MB, then run "sudo pmset -a hibernatemode 3" at a terminal. That should create a file /var/vm/sleepimage . (If you've got secure virtual memory enabled, you should use 7 rather than 3 so that encrypted hibernation mode isn't used (yeah, this isn't secure). For some reason encrypted hibernation doesn't work, I'm unsure why... Don't set it to 7 if you don't have secure virtual memory.)

You can set it to 1 (or 5 with secure VM) if you want to hibernate and shut down immediately on sleep without suspending to ram. 0 will disable hibernation.

Reboot (to set the Open Firmware var), and then try shutting the lid and wait for the light to start pulsing. Don't try ripping the power out yet, wake it normally and see what it says in /var/log/system.log . There should be a line like

Nov 2 14:27:17 computername kernel[0]: System SafeSleep

indicating that it worked.

If that seems OK, try it for real. Sleep it (make sure that the light starts pulsing), remove the power and battery (wait for the sleep light to stop, might take a while on powerbooks), put power back, then boot it with the power button. It should show a progress thing, then flicker a bit then come back where you left it (with a fair bit of disk activity). A word of warning — don't ever use target disk mode on a mac while it is hibernated, since you'll likely end up with filesystem corruption.

Let me know how it goes, and good luck.

Troubles

I've now had a bit of feedback from people who've tried it. I've had reports of the following machines working:

iBook G4 — 12" 1GHz, 14" 1.2GHz, G4 800MHz

PowerBook — 1.25GHz, 1GHz, 1.5GHz, 15" 1.67GHz

eMac — 1GHz (running 10.4.3 Server)

Mac mini — 1.4GHz

In general, it seems most G4s from September 2003 onwards should work (all AlBooks, though I'm unsure about the 12" 867Mhz one). If anyone has it working on a G5, I'd be interested to hear.

I've had a report from Peter Steiner that his 12" 867MHz PowerBook's fan stopped working with Safe Sleep mode enabled, and that the clock stopped while sleeping. It seems that a few people have had troubles with the 867MHz 12" PowerBooks — it's probably best not to use it on them.

I've seen a few reports of Bluetooth being enabled and not being able to be turned off, I've got no idea why that'd be happening (informed suggestions welcome :). Some people have also found that the clock doesn't keep time during sleep — it might be model specific, I'm not sure.

A couple of people also had problems with bad hibernate images, which would repeatedly kernel panic, but rebooting would just start the bad image again. This can happen if you don't set hibernatemode properly with secure virtual memory. If a bad hibernate image keeps trying to boot then crashing, try the following:

Reboot the mac holding down Command-Option-O-F to get in to Open Firmware.

to get in to Open Firmware. Type setenv boot-image , press return, then boot . (If you have an OF password set, you'll be prompted for it).

Matt Johnston - matt @ ucc.asn.au

Updated 17 November 2005 (created 2 November 2005)

Other Apple Stuff

Home