Sunday, February 3, 2008

Eee-Pc fast boot with Ubunutu

This tutorial shows how to substantially reduce the boot time of an Ubuntu Eee-Pc. The stock boot time is between 45 seconds and 1 minute depending of compiz being used or not. On top of that, you want to add another 15 seconds to type your password, get access to the internet and load firefox. My Eee goes from cold dead to enjoying the internet in about 15 seconds (more, depending on how you count bios spent time).



This tutorial is for experienced linux users with knowledge of compiling and installing stuff. It does not intend to build a fully working system with webcam, sound and so on. You will have to customize your install to suit your needs.

The basic idea is to get rid of the init scripts (from /etc/init.d) and only do the necessary steps (no hardware detection is needed since the eee has static hardware; no services are run: we only want to connect to the internet and be able to check a webpage). Then, run lightweight alternatives to Xorg and the gnome desktop. Our choices will be kdrive (also known as Xserver, a non-modular server configured at compilation time) and dwm, a primitive looking fullscreen oriented window manager, also configured at compilation time).
  1. Compile Xvesa (from kdrive)
  2. Compile dwm and dmenu
  3. Write the init script, a X session script and some unnecessary eye-candy
  4. Change the kernel command line to run a customized init process
  5. Customize your kernel (not done yet)
1. Compiling Xvesa

You can take a look at the xserver page for compilation instructions. It works nicely, but it is a bit long. Obviously, you don't want to do it on your eee; a more powerful machine would be nicer. Here is the git command to get the source code:
git clone git://anongit.freedesktop.org/git/xserver
You also need to install build tools and libraries. Try to ./configure --enable-kdrive, get the library name from the error and install it. Here is a certainly incomplete list from my bash history:
libxv-dev libcairo2 libssl-dev libpciaccess-dev libpixman-1-dev
If you are building under Gutsy, libpixman-1 is outdated: manually install the Hardy package with dpkg. Also take the corresponding lib package that you will install on both your eee and your build machine.

I also installed build dependencies for the package xorg-xserver-core. Then, run ./configure --enable-kdrive && make. Wait and get Xvesa in xserver/hw/kdrive/vesa. This will be your lightweight X11 server. Cool, isn't it?

There are a bunch of other specialized servers with drivers for different graphic cards. I tried Xfbdev and Xi810 without success. Xvesa does not have much hardware acceleration but it is enough for terminal works and basic web browsing.

For a matter of conciseness, all additional scripts and programs will be assumed to be available in your path on your eee (put them in /bin or whatever).

2. Compile dwm and dmenu

First, download the sources, then edit config.h and use make clean install to build and install it. Read the website carefully about shortcomings and limitations. You can also try fluxbox or even metacity if you find dwm too crude. But I like the idea of keeping things simple and fast.

You don't really need dmenu (from the same author), but it will help to get a shutdown/reboot dialog. Without such a dialog, you will have to type commands in a terminal or press the power button for 5 seconds. Yeah, this is hardcore.

dwm is easy to use, but not user friendly. So, you can man dwm or remember these few shortcuts:
  • close a window: <alt><shift>C
  • goto workspace n (n from 1 to 9): <alt>n
  • next window: <alt>k (<alt>j, or <alt><tab>)
  • maximize window: <alt><enter>
  • open terminal: <alt><shift><enter>
  • run a program: <alt>p (with dmenu installed, then type the name of the program)
  • quit dwm (does not quit X): <alt><shift>q
You may want to checkout the website for the philosophy of tags. It is a neat idea that will always send your browser to the workspace "www" for instance.

3. Write the init script and others

The Ubuntu provided init scripts are really over bloated and do a lot of stuff so that your linux experience look like a windows (or mac) experience. The drawback is that you get to wait quite a long time before you can do anything. For that one, we will follow the Vista approach: show a user interface as soon as possible and load things in the background. Ok, Vista is sluggish, and you don't want that. Let's forget about running an anti-virus or vendor added crapware. You will just get X ready and then load everything to get a wifi/internet connection. To get that working, I looked at the primitive boot scripts in rcS and did some trial and error to get the missing steps.

Here is the init script fastboot.sh:
#!/bin/bash

# set environment
export DISPLAY=:0
export \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin

# remount root dir, prepare tmp for X11, set permissions in /dev
mount -o remount,rw /
rm -rf /tmp
mkdir /tmp
chmod 777 /tmp
mkdir -p /tmp/.X11-unix
chown 0:0 /tmp/.X11-unix
chmod 1777 /tmp/.X11-unix
chmod o+rw /dev/null /dev/pty* /dev/tty*

# load mouse module (not sure if evdev is necessary)
modprobe evdev
modprobe psmouse

# tweak vesa bios resolution to recognize lcd panel
915resolution 5c 800 480 32

# set hostname
hostname eeepc

# run X11 server with adequate resolution, mouse and keyboard
Xvesa :0 -nolisten tcp -screen 800x480x24 -mouse ps2 \
-keybd keyboard,,xkbmodel=pc105,xkblayout=us &

# run x session (window manager...) as an unprivileged user
su user -c session.sh &

# load a few more modules and setup wifi (wep), get ip address
modprobe battery
modprobe ath_pci
ifconfig ath0 up
iwconfig ath0 essid **************
iwconfig ath0 key **************
dhclient ath0

# run bash in case things went wrong
bash

Don't forget to replace your user name, network essid and wep password. You are left on your own if your wireless setup is different (wpa or others). Of course, this is not secure at all, but who cares, we focus on shortening boot time, not improving security.

Then, comes your X session. I used to run everything in the fastboot.sh script but getting a non-privileged user is better if you tend to type things like rm -rf /session.sh:
#!/bin/bash
export DISPLAY=:0
export \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# wait for X
sleep 0.1

# run session applications
firefox &
uxterm &

# window manager
notification.sh | dwm
Nothing particular about this one. Just make sure that the environment is re-setup. The last line runs the window manager and is an opportunity to discover a nice feature of dwm: text read from stdin is displayed in the notification zone. So, let's make it pretty with date, time, wifi and battery status.
#!/bin/bash

# loop forever
while [ 1 ]
do
# get the date in "Month Day Time" format
DATE=`date '+%b %d %H:%M'`

# get battery percentage and a + or - for charing/discharing
BATTERY=`cat /proc/acpi/battery/BAT0/state \
| awk '
/^remaining/{percent=$3}
/charging$/{state="+"} \
/ discharging$/{state="-"}
END{print percent "%" state}'`

# get wifi signal quality and set to "*" if not available
WIFI=`iwconfig ath0 | grep Quality | cut -f2 -d= | cut -f1 -d/`"%"
if [ "$WIFI" == "%" ]; then WIFI="*"; fi

# display a + if an ip address is set (internet connection available)
if [ "`ifconfig ath0 | grep 'inet addr'`" != "" ]; then WIFI=$WIFI"+"; fi

# display everything and wait 1 second before the next update
echo "W:$WIFI B:$BATTERY $DATE"
sleep 1
done

That looks quite obscure but that gives you minimum status information about your eee. Note the nice +/- display for the battery and the + appearing when dhcp negotiations succeeded.



One last thing. There are no shutdown facilities available in dwm, and pressing the power button is not recommended. So there are two things to do: setup a shortcut in dwm's config.h and design a nice dialog box for confirmation. Here is the config line (at the end of the file):
//{ MODKEY|ShiftMask, XK_q, quit, NULL },
{ MODKEY|ShiftMask, XK_q, spawn, "shutdown.sh" },

Recompile and reinstall. Here is shutdown.sh:
#!/bin/bash

ANSWER=`echo -e "Cancel\nShutdown\nReboot"|dmenu -b -p "Quit?"`

if [ "$ANSWER" == "Shutdown" ]; then
poweroff -f -i
elif [ "$ANSWER" == "Reboot" ]; then
reboot -f -i
fi
Simple yet efficient. For it to work, you will have to chmod +s /sbin/reboot. This does not take care (yet) of closing cleanly running programs. So use <alt><shift<C on firefox if you don't want to get the "restore session" dialog the next time you run it.




4. Change the kernel command line to run a customized init process

You can press escape when grub shows up; then edit the command line: remove "splash" and add "init=/fastboot.sh". Do it permanently in /boot/grub/menu.lst and also set the timer to zero to save additional boot time (pressing escape will be a little tricky though).

5. Customize your kernel (not done yet)

There is a lot of potential in recompiling a kernel with only the required drivers, getting rid of the initrd which runs blackbox and does a lot of stuff like checking your filesystems and mounting them. But that's another story...