Sokrates
Building a new kernel that supports suspend
30 August 2006

Summary
  • It may not be necessary to build a new and patched kernel
  • wireless should already work fine, and does for many
  • sofware suspend should already work
  • suspend to RAM is likely iffy, but this is not resolved in 2.6.12
  • Ubuntu doesn't even have the source ready for 2.6.12, so not much point rebuilding
In favor of rebuilding
  • get rid of unneded modules
  • de-modularize critical components
  • centrino optimizations
  • sse2 and mmx2
  • mmc -- sdhci support for the SD card reader is in 2.6.17-rc1
Notes from various places
Here is Martin's guide:
  • get the 2.6.12 kernel
    • it's of course possible some of these issues have been resolved in 2.6.13 -- check first

  • In order to have the wired network card (tg3) wake up properly after ACPI sleep, a kernel patch is needed. Download the patch from gmane.org. (Tip: Be careful to save the patch in a proper format, i.e. with ‘@’ and not ‘<at>’ in it)
    • /usr/src/portdrv.patch
    • # cd /usr/src/linux-2.6.12
      # patch -p1 < ../portdrv.patch
      # make && make modules_install
      # cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.12
      # rm /boot//initrd-2.6.12.img
      # mkinitrd /boot/initrd-2.6.12.img 2.6.12
      # reboot
  • In the 2.6.12 kernel, the ipw2200 module may not build. I downloaded the following files (try to use the Debian source packages instead):
    ipw2200-1.0.4.tgz, ieee80211-2.6.12.patch (from http://ipw2200.sourceforge.net/patches/ieee80211-2.6.12.patch) and ipw2200-fw-2.3.tgz (firmware for the 1.0.4 version). Suppose you’ve downloaded them all in /root, untar and install:
    # cd /root
    # untar xzf ipw2200-fw-2.3.tgz
    # cd ipw2200-1.0.4
    # patch net/ieee80211.h ../ieee80211-2.6.12.patch
    # make
    # make install
    # cd /lib/firmware/
    # tar xzf /root/ipw2200-fw-2.3.tgz
    # modprobe ipw2200
    # dmesg
  • Add swsusp2

First, fix the ipw2200 wireless module (the config option for suspend2 changed name in 2.1.8.6 from CONFIG_SOFTWARE_SUSPEND2_BUILTIN to just CONFIG_SUSPEND2):
Edit the source code of the ipw2200 1.0.4 module:

# cd /root/tarballs/ipw2200-1.0.4/
# cp ipw2200.c ipw2200.c.orig
# emacs ipw2200.c

And change the line

#ifdef CONFIG_SOFTWARE_SUSPEND2_BUILTIN

to

#ifdef CONFIG_SUSPEND2

and compile and install it:

# less INSTALL
# make
# make install
# cd /root/tarballs
# tar xjf software-suspend-2.1.9.5-for-2.6.12.tar.bz2
# cd /usr/src/linux-2.6.12
# /root/tarballs/software-suspend-2.1.9.5-for-2.6.12/apply
...
All happy!

Recompile the kernel (assuming you already have a .config file, else first ‘cp /boot/config-2.6.XXX .config‘). From within /usr/src/linux-2.6.12:
IMPORTANT: My swap partition is /dev/hda6 - your’s probably something else - find it with ‘cat /etc/fstab | grep swap‘ or ‘fdisk -l|grep -i swap‘.

# make oldconfig
...
CONFIG_SUSPEND2=y
CONFIG_SUSPEND2_FILEWRITER=y
CONFIG_SUSPEND2_SWAPWRITER=y
CONFIG_SUSPEND2_USERSPACE_UI=y
SUSPEND2_TEXT_MODE=n
CONFIG_SUSPEND2_DEFAULT_RESUME2=\"/dev/hda6\"
CONFIG_SUSPEND2_KEEP_IMAGE=y
CONFIG_SUSPEND2_CHECK_RESUME_SAFE=y
CONFIG_CRYPTO_LZF=y

# make

While compiling, download the hibernate script tarball and install it:

# cd /root/tarballs
# tar xzf hibernate-script-1.09.tar.gz
# cd hibernate-script-1.09
# less README
# ./install.sh
# cp init.d/hibernate-cleanup.sh /etc/init.d/hibernate-cleanup.sh

Back in /usr/src/linux-2.6.12, install the new kernel:

# make modules_install
# cp -f arch/i386/boot/bzImage /boot/vmlinuz-2.6.12-swsusp2
# mkinitrd -f -v /boot/initrd-2.6.12-swsusp2.img 2.6.12

Update /etc/grub.conf (NOTE: change /dev/hda6 to your swap partition):

...
title Fedora Core (2.6.12-swsusp2)
root (hd0,2)
kernel /vmlinuz-2.6.12-swsusp2 ro root=LABEL=/ resume2=swap:/dev/hda6
initrd /initrd-2.6.12-swsusp2.img
...

Update the newly baked initrd:

# cd /root/
# mkdir myinitrd
# cd myinitrd
# gzip -dc < /boot/initrd-2.6.12-swsusp2.img |cpio -i

and edit the unpacked init to include the two extra lines the lines after ‘mount -t sysfs /sys /sys‘:

#!/bin/nash
mount -t proc /proc /proc
setquiet
echo Mounted /proc filesystem
echo Mounting sysfs
mount -t sysfs /sys /sys
echo Activating Software Suspend 2
echo > /proc/software_suspend/do_resume
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mkdir /dev/pts
mkdir /dev/shm
echo Starting udev
/sbin/udevstart
echo -n \"/sbin/hotplug\" > /proc/sys/kernel/hotplug
echo \"Loading jbd.ko module\"
insmod /lib/jbd.ko
echo \"Loading ext3.ko module\"
insmod /lib/ext3.ko
/sbin/udevstart
echo Creating root device
mkrootdev /dev/root
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
echo Switching to new root
switchroot --movedev /sysroot

Install the new initrd:

# cp /boot/initrd-2.6.12-swsusp2.img /boot/initrd-2.6.12-swsusp2-without-do_resume.img
# find . | cpio -o -c | gzip -9 > /boot/initrd-2.6.12-swsusp2.img

You might want to backup your personal data as well as the /etc/ folder before continuing in case you fuck up your entire system.

In order to reduce the chance of a total disaster something goes wrong with the hibernation, you should put the following line in your /etc/rc.local (this prevents the system to perform a resume after the the sequence ‘hibernate - boot a noresume kernel - reboot the resume kernel’ which otherwise will cause a filesystem crash as the noresume kernel will leave the system in another state…):

/etc/init.d/hibernate-cleanup.sh

Because I’m using the 915resolution VBIOS hack, and this has to be patched each and every time the system boots, the hibernation script must do this. Therefore, add the following line to /etc/hibernate/hibernate.conf (from the Software Suspend 2 Wiki):

OnResume 86 915resolution 3c 1280 768

Now, reboot with the new kernel (important). Then, from within X, issue the command ‘hibernate‘ as root. After a few seconds (20?), the computer turns itself off.
Next time you power on, boot from the same kernel (important) and watch the system bring you right to your X session instead of doing the whole boot sequence. If you’ve chosen to lock the X session you have to touch a key to wake up the display. For me it took about 35 seconds from I pushed the powerbutton until I could unlock my X session, and in total less than 55 seconds until the resume bar was 100 percent. That is with quite some programs running, and 1.2GB RAM.

See my hibernation.conf in the Files section (I use KDE). I’ve successfully used hibernation while having an active wireless network connection. One should maybe be careful if hibernating with AC power plugged and then resumes unplugged.

This rocks bigtime!!!


 

 

top