HOWTO Userspace Software Suspend (uswsusp)

From Gentoo Linux Wiki

Jump to: navigation, search



Warning: This page is a work in progress, use at your own risk.

Contents

[edit] About

Suspending or hibernating are alternatives to halting (turning off) the OS when powering down. Instead of closing all running applications, it writes the contents of the RAM (Random Access Memory) to the disk. Upon restarting the computer, the RAM is restored and users can continue exactly where they left off. The RAM may be stored either on a swap partition or a file. In most cases, a swap partition will need at least as much capacity as the RAM. A workaround is available for computers with large amounts of memory which is usually not completely used. Many users use TuxOnIce (formerly Software Suspend v2) this method works for many people but has the following disadvantages.

  • Not supported by mainstream kernel developers
    • This means you always have to use an older kernel
    • Or patch a newer kernel yourself
  • It is implemented in a very unclean way

[edit] What the solution in this howto will eventually provide

[edit] Before you start

  1. Make a backup
  2. Some prior Linux/Gentoo knowledge is required:

[edit] Install

[edit] Kernel Configuration

The kernel has to be configured to support software suspend. It is recommended to use a 2.6.17 kernel or above. I used gentoo-sources-2.6.24-r4 (latest stable at the moment of writing). Make sure you enable these features:

Linux Kernel Configuration: Enable necessary features
  General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
  Power management options (ACPI, APM)  --->
    [*] Suspend to RAM and standby
    [*] Hibernation (aka 'suspend to disk')
    (/dev/<swap-partition>) Default resume partition

Genkernel users may be interested in Gentoo Bugs: Add support to genkernel for userspace suspend/resume (uswsusp).

[edit] Installing needed packages

Emerge sys-power/suspend and configure it. Replace X with your swap partition (i.e. hda1).

File: /etc/suspend.conf
snapshot device = /dev/snapshot
resume device = /dev/X
#image size = 350000000
#suspend loglevel = 2
compute checksum = y
compress = y
#encrypt = y
#early writeout = y
#splash = y
Note: todo: encryption and splash images

[edit] Preparing the initramfs image

We will create a directory with all the necessary files for our initramfs image. But first of all emerge sys-apps/busybox with the static use flag enabled. Then create a directory with the following files in it:

File: Contents of the initramfs image
bin
bin/busybox (copy the STATIC version from /bin)
bin/resume (copy this from /usr/lib/suspend)
dev
dev/snapshot (copy this from /dev, use cp -a to copy it)
etc
etc/suspend.conf (copy this from /etc)
init

We will refer to this directory as /path/to/structure.

init is a text file which will be executed while booting the kernel:

File: init
#!/bin/busybox ash

local X ROOT RUNLEVEL

# Preliminary stuff.
mkdir -p /proc /sys /mnt
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mdev -s

# Try to resume. This never returns if it succeeds.
resume

# Parse the command line for relevant options.
for X in `cat /proc/cmdline`
do
        case "$X" in
                root=*) ROOT=${X#root=} ;;
                [0-6Ss]) RUNLEVEL=${X} ;;
        esac
done

# Mount and switch root.
mount -o ro ${ROOT} /mnt
umount -f /sys  || umount -l /sys
umount -f /proc || umount -l /proc
exec switch_root /mnt /sbin/init ${RUNLEVEL}

Make sure resume, busybox and init are executable:

chmod +x bin/resume bin/busybox init

Now create the initramfs image:

cd /path/to/structure
find * | cpio --quiet -o -H newc | gzip -9 > /boot/uswsusp-image

Or if you are using media-gfx/splashutils (replace 1280x1024 with your resolution and livecd-2007.0 with your preferred theme):

splash_geninitramfs -o /path/to/structure --no8bpp -r 1280x1024 -g /boot/uswsusp-image livecd-2007.0

[edit] Bootloader configuration

[edit] Grub

Edit your bootloader configuration. Add a parameter root to the kernel line with the device that contains your root partition (i.e. hda5). And specify the path to the initramfs image after initrd.

File: /boot/grub/grub.conf
title  Gentoo GNU/Linux 2.6.24-gentoo-r4
root (hd0,5)
kernel /boot/vmlinuz-2.6.24-gentoo-r4 vga=792 splash=verbose,fadein,theme:emergence quiet CONSOLE=/dev/tty1 root=/dev/X
initrd /boot/uswsusp-image

If all went well you should now be able to boot using your newly built kernel.

[edit] Suspending

s2ram is a wrapper around the kernel's suspend-to-RAM mechanism allowing the user to perform some graphics adapter manipulations from the user land before suspending and after resuming that may help to bring the graphics (and the entire system) back to life after the resume. Incorporates the functionality of vbetool and radeontool as well as some tricks of its own. Includes a list of working hardware configurations along with the appropriate sets of operations to be performed to resume them successfully.

s2disk is the reference implementation of the userspace software suspend (µswsusp); it coordinates the steps necessary to suspend the system (such as freezing the processes, preparing the swap space, etc.) and handles image writing and reading. s2disk already supports compression and encryption of the image and other features (e.g. a nice progress bar, saving the image on a remote disk, playing tetris while resuming, etc.) can be easily added.

s2both combines the funtionalities of s2ram and s2disk and it's very useful when the battery is almost depleted. s2both write system snapshot to the swap (just like s2disk) but then put the machine into STR (just like s2ram). If the battery has enough power left you can quickly resume from STR, otherwise you can still resume from disk without loosing your work.

[edit] Troubleshooting

[edit] Errors while booting

[edit] Kernel panic - not syncing: No init found. Try passing init= option to kernel.

You need to use the static version of busybox. Make sure sys-apps/busybox is compiled with the use flag static enabled and you've copied /bin/busybox.static.

[edit] Kernel panic - not syncing: Attempted to kill init

Verify if dev/snapshot is a character device:

ls -l /path/to/structure/dev/snapshot
crw-rw---- 1 root root 10, 231 Apr  4 01:32 /path/to/structure/dev/snapshot
^ this means it is a character device

If not, copy it with:

cp -a /dev/snapshot /path/to/structure/dev/snapshot

[edit] Sample /init and initramfs by another user

I am using this init script and initramfs source together with fbsplash:

File: init
#!/bin/busybox sh

local X ROOT RUNLEVEL

# Preliminary stuff.
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mdev -s

# Try to resume. This never returns if it succeeds.
/bin/resume

# Parse the command line for relevant options.
for X in `cat /proc/cmdline`
do
	case "$X" in
		root=*) ROOT=${X#root=} ;;
		[0-6Ss]) RUNLEVEL=${X} ;;
	esac
done

# Mount and switch root.
mount -o ro ${ROOT} /root
umount -f /sys  || umount -l /sys
umount -f /proc || umount -l /proc
exec switch_root /root /sbin/init ${RUNLEVEL}
File: initramfs
dir /sys 0755 0 0
dir /proc 0755 0 0
dir /root 0755 0 0

dir /dev 0755 0 0
nod /dev/console 0600 0 0 c 5 1
nod /dev/tty1 0600 0 0 c 4 1
nod /dev/zero 0600 0 0 c 1 5
nod /dev/mem 0600 0 0 c 1 1
dir /sbin 0755 0 0
file /sbin/v86d /sbin/v86d 0755 0 0

dir /dev 0755 0 0
dir /dev/fb 0755 0 0
dir /dev/vc 0755 0 0
dir /dev/misc 0755 0 0
nod /dev/null 0600 0 0 c 1 3

dir /etc 0755 0 0
dir /etc/splash 0755 0 0
dir /etc/splash/livecd-2007.0 0755 0 0
file /etc/splash/livecd-2007.0/1280x1024.cfg /etc/splash/livecd-2007.0/1280x1024.cfg 0644 0 0
file /etc/splash/livecd-2007.0/Vera.ttf /etc/splash/livecd-2007.0/Vera.ttf 0644 0 0
dir /etc/splash/livecd-2007.0/images 0755 0 0
file /etc/splash/livecd-2007.0/images/background-1280x1024.png /etc/splash/livecd-2007.0/images/background-1280x1024.png 0644 0 0
file /etc/splash/livecd-2007.0/images/verbose-1280x1024.png /etc/splash/livecd-2007.0/images/verbose-1280x1024.png 0644 0 0
file /etc/splash/livecd-2007.0/images/overlay-1024.png /etc/splash/livecd-2007.0/images/overlay-1024.png 0644 0 0
dir /lib 0755 0 0
dir /lib/splash 0755 0 0
dir /lib/splash/sys 0755 0 0
dir /lib/splash/proc 0755 0 0
dir /root 0755 0 0
slink /sbin/splash_helper /sbin/fbcondecor_helper 0755 0 0
file /sbin/fbcondecor_helper /sbin/fbcondecor_helper 0755 0 0

dir /dev 0755 0 0
nod /dev/snapshot 0600 0 0 c 10 231
dir /bin 0755 0 0
file /bin/busybox /bin/busybox.static 0755 0 0
file /bin/resume /usr/lib64/suspend/resume 0755 0 0
dir /etc 0755 0 0
file /etc/mdev.conf /dev/null 0644 0 0
file /etc/suspend.conf /etc/suspend.conf 0644 0 0
file /init /root/init.sh 0755 0 0

I am also using this Kernel config setting:

CONFIG_INITRAMFS_SOURCE="/root/initramfs"

Several directories are mentioned redundandly in the initramfs source file, because the blocks were mostly just copied from the samples for v86d, splashutils, and this tutorial. And it makes it easier for me to add or remove stuff. A little addition is that I do not create any folders in /init, but already have them in the ramdisk.

Note that at least for sys-apps/busybox-1.10.1-r3 you need /etc/mdev.conf, otherwise mdev will refuse to work and just spit out lots of errors about that file being missing. Note also that sys-apps/busybox-1.10.1-r3's mdev has a bug with Kernel 2.6.25 which makes it create only character devices instead of block devices, which will make you unable to mount any partition (neither root- nor resume-partition). This is fixed in 1.10.3 (which is not yet in Portage at the time of this writing).

[edit] Resuming didn't work (a 3rd User)

Maybe I'm the only person, but for me I had to change the procedure for creating the initramfs image. That caused to have the included files in the root of the image but not in /path/to/structure/.

First change to that directory:

cd /path/to/structure

Now create the initramfs image:

find . | cpio --quiet -o -H newc | gzip -9 > /boot/uswsusp-image

[edit] See also

Personal tools