Table of Contents

Booting into a "powersaving" version of Ubuntu

Ubuntu Powersaving
In this article I will explain how to boot into different environments with the same operative system (Ubuntu in this case) from the grub bootloader.

I wanted this setup to have an option in the boot menu to load a light and powersaving environment in my laptop, so I can use it on trains or air planes without AC outlet as long as I can.

Also you can use this setup to have, for example, a standard Ubuntu, a Media Center Ubuntu (using Elisa or XBMC), a Text Console Ubuntu (for maintenance duties), a GNOME Ubuntu, a KDE Ubuntu, etc…

Example

Grub menu:

 
 --------------------------------------------- 
 |                                           | 
 |                GRUB MENU                  | 
 |                                           | 
 |   - Ubuntu                                | 
 |   - Ubuntu Powersave                      | 
 |   - Ubuntu Powersave (no wifi)            | 
 |   - Windows                               | 
 |                                           | 
 |             Please select...              | 
 |                                           | 
 --------------------------------------------- 


Each of the Ubuntu selections will boot the same Ubuntu OS, but with different environments by default. “Ubuntu” will load the standard GNOME environent, “Ubuntu Powersave” will load a Openbox session, and “Ubuntu Powersave (no wifi)” will load Openbox without wireless networking enabled.

Overview of needed changes


Modifying upstart to allow boot parameters

Upstart is the default init daemon in Ubuntu, which means it is the program that manages which services must be loaded at boot time. In the old System-V init you could tell in which runlevel you wanted to boot, but upstart hasn't that option.

So what we need is to modify Ubuntu's default upstart to allow booting into different runlevels (by default, Ubuntu boots into runlevel 2).

Ok, let's start working. We need to edit /etc/event.d/rc-default. Open that file (as root) and change its content to this:

# rc - runlevel compatibility 
# 
# This task guesses what the "default runlevel" should be and starts the 
# appropriate script. 
 
start on stopped rcS 
 
script 
	runlevel --reboot || true 
 
	if grep -q -- "init [2-5S]" /proc/cmdline; then 
	    RL="$(sed -ne 's/.*init \([2-5S]\).*/\1/;p' /proc/cmdline || true)" 
	    if [ -n "$RL" ]; then 
	        telinit $RL 
	    else 
	    	telinit 2 
	    fi 
 
	elif grep -q -w -- "-s\|single\|S" /proc/cmdline; then 
	    telinit S 
 
	elif [ -r /etc/inittab ]; then 
	    RL="$(sed -n -e "/^id:[0-9]*:initdefault:/{s/^id://;s/:.*//;p}" /etc/inittab || true)" 
	    if [ -n "$RL" ]; then 
			telinit $RL 
	    else 
			telinit 2 
	    fi 
 
	else 
	    telinit 2 
	fi 
 
end script

With this new rc-default, upstart can now boot into different runlevels. You just need to add init 3 to the desired grub's menu.lst file to boot into runlevel 3.

Modifying grub's menu.lst

Now we need to add the to the boot menu a new option to load into a runlevel different from the default one.

So open /boot/grub/menu.lst as root, copy your default boot option, which should look like:

 
title		Ubuntu 8.04.1, kernel 2.6.24-21-generic 
root		(hd0,1) 
kernel		/boot/vmlinuz-2.6.24-21-generic root=UUID=your_root_partition_uuid ro quiet splash 
initrd		/boot/initrd.img-2.6.24-21-generic 
quiet 

And paste it with some changes:

 
title		Ubuntu GNU/Linux (Powersaving) 
root		(hd0,1) 
kernel		/boot/vmlinuz-2.6.24-21-generic  root=UUID=your_root_partition_uuid ro quiet init 3 
initrd		/boot/initrd.img-2.6.24-21-generic 
quiet 


Plase note that I've removed the splash option, as I don't want the graphical progress bar on boot, and more important init 3, which will tell upstart to boot into runlevel 3.

So now, if you restart your computer, you will be able to boot into the Ubuntu Powersaving mode. Everything will load as the default option, because we haven't changed to contents of the runlevel 3 (will do in next step), but you can check that eveything's ok running on a terminal:

$ runlevel
$ N 3



Setting up a clean runlevel 3

Now we're going to clean up the runlevel 3 to make it a bit faster on boot, and more powersaving. Note that this changes are good to me, but maybe you will need others.

First thing I did was mimc the default runlevel 2 in runlevel 3 (in Ubuntu they are a but different).

$ cd /etc/rc3.d/
$ sudo rm *
$ sudo cp -a ../rc2.d/* .

Now you have to remove unnecessary services. You can do it by hand (deleting or removing execute permissions) or using the nifty sysv-rc-conf, which is a console editor for runlevel services.

$ sudo apt-get install sysv-rc-conf
$ sudo sysv-rc-conf –s 3

In my system, I have these enabled:

/etc/rc3.d/S01policykit 
/etc/rc3.d/S05vbesave 
/etc/rc3.d/S10acpid 
/etc/rc3.d/S10powernowd.early 
/etc/rc3.d/S10sysklogd 
/etc/rc3.d/S11klogd 
/etc/rc3.d/S12dbus 
/etc/rc3.d/S20apmd 
/etc/rc3.d/S20atieventsd 
/etc/rc3.d/S20hddtemp 
/etc/rc3.d/S20hotkey-setup 
/etc/rc3.d/S20makedev 
/etc/rc3.d/S20powernowd 
/etc/rc3.d/S20smartmontools 
/etc/rc3.d/S24hal 
/etc/rc3.d/S25pulseaudio 
/etc/rc3.d/S99acpi-support 
/etc/rc3.d/S99laptop-mode 
/etc/rc3.d/S99rc.local 
/etc/rc3.d/S99rmnologin 
/etc/rc3.d/S99stop-readahead

Note that I'm not using any graphical login (GDM), so I need to login in text mode, and then use startx to use a GUI.

Installing lightweight software

In my laptop, I'm using:

If you google a bit, you'll find many guides on how to use really light software.

You can read how I configured my Openbox environment here.

Final performance tweaks

These are just suggestions, as my hardware configuration may be different from yours.

To finish, I've made some tweaks to my system to disable some drivers (bluetooth and wireless network) and some os tricks to spend less power.

I've created a script which runs at boot time which disables hdi_usb (bluetooth) and ipw2200 (wifi). It also runs some commands which were advised by powertop, an utility which helps you to save power.

Here's the script:

#! /bin/sh -e 
 
# Get lsb functions 
. /lib/lsb/init-functions 
. /etc/default/rcS 
 
# Disable Bluetooth if requested 
if grep -q -w "nobt" /proc/cmdline; then 
	log_begin_msg "Disabling Bluetooth..." 
	hciconfig hci0 down 
	rmmod hci_usb 
	rmmod bluetooth 
	log_end_msg $? 
fi 
 
# Disable wireless if requested 
if grep -q -w "nowifi" /proc/cmdline; then 
	log_begin_msg "Disabling Wireless..." 
	ifconfig wlan0 down 
	rmmod ipw2200 
	rmmod ieee80211 
	killall wpa_supplicant 
	log_end_msg $? 
fi 
 
# Fix dirty writeback 
log_begin_msg "Fix dirty writeback..." 
echo 1500 > /proc/sys/vm/dirty_writeback_centisecs 
log_end_msg $? 
 
# Sound card power save 
log_begin_msg "Sound card power save..." 
echo 1 > /sys/module/snd_ac97_codec/parameters/power_save 
log_end_msg $?

I saved this script as S30powersaving_mode and add it to the default scripts to run at boot.

$ chmod 755 S30powersaving_mode
$ sudo mv S30powersaving_mode /etc/init.d/
$ cd /etc/rc3.d/
$ sudo ln -s ../init.d/S30powersaving_mode

To disable bluetooth or wireless at startup, you have to use nobt or nowifi in the kernel line in your grub's menu.lst.

Mine looks like this:

title		Ubuntu GNU/Linux (Powersave No Wifi) 
root		(hd0,1) 
kernel		/vmlinuz root=UUID=mi_uuid ro quiet init 3 nobt nowifi 
initrd		/initrd.img 
quiet



Conclusion

So now you have a way to log in your computer and save some battery power. Hope everything's work as expected. And remember, comments are welcome!

References: