|
|
Speedup Arch Boot Process
Jun 27th 2008
My Arch Linux box boots in 15 seconds. Schweeet… And that’s not a fresh Arch with only base apps installed, it’s a full-fledged Arch with XFCE and bunch of apps that I need (no redundancy, thanks). The only OS came close is Mac OS 10.4, which boots in 19 seconds. Windows XP boots in 27 seconds (SP2) and 30 seconds (SP3), both nlited, XUbuntu in 35 seconds, Vista (vlited) in 44 seconds, and openSUSE (already stripped down) in 50 seconds. All in the same machine (wait… 10.4? Go figure… hehe…). In this guide I will explain some of the tweaks I did related to the boot process speedup.
Disclaimer. This guide is written for people who like to tinker with their system, like to get their feet wet, and don’t cry when something bad happens. We will be working entirely on CLI so if you’re not comfortable with it, go get some coffee and watch movies instead. This guide contains tips and tricks from various places, notably the Arch Wiki and Forum, with some of them are the result of my own tweaking. These tweaks are applied on my system and it never had any craches or freezes or any other problems. It just works. Your mileage may vary. One strict rule of engagement: Always make a backup of everything you edit!
Use a faster filesystem
Various filesystems exist and what you’ll be using is entirely up to you. Every FS has goods and bads, but for this guide we’ll be using the fastest FS while maintaining high reliability and low CPU usage. My choice is JFS. It’s reasonably fast, if not the fastest at some points, it’s journaled, stable, reliable, and has very low CPU utilizations. Other options are ReiserFS (quite stable, faster), and Reiser4 (unstable, very fast). Changing filesystem type may require you to first erase the partition. If this isn’t viable, you can use whatever you already have right now. Or, do the tar routine. Or, use clonezilla. Whatever.
Trim your initrd
Go edit /etc/mkinitcpio.conf and trim it to your needs. Make it as compact as possible. This config will be used to generate an initrd, which will be loaded by the boot loader, sets your hardware (loading modules, etc) and mounting the filesystem. After that, it gives the control to the kernel. Delete hooks that you don’t plan on using, or don’t need to be loaded at this stage of booting process. Hardware configs will be done later after the kernel loads instead. In my case, my mkinitcpio.conf looks like this:
MODULES=""
BINARIES=""
FILES=""
HOOKS="autodetect base udev sata filesystems"
That will generate a very small initrd which is enough to mount the root filesystem and loads the kernel.
Trim your rc.conf
Two of the main delay when booting is loading daemons and modules. The other would be loading udev, which we will see later on. If you have more fancy hardwares, the kernel will load more modules to activate them. The wisest step would be disable the ones you don’t need via BIOS. The second wisest step would be to blacklist the modules. In short, just load modules and daemons you need. As for the daemons, replace some of them with more lightweight ones, FAM with Gamin, for example. My /etc/rc.conf looks like this (some lines omitted):
...
MOD_AUTOLOAD="yes"
MODULES=(powernow-k8 fglrx)
DAEMONS=(preload hal @cpufreq @network)
...
Trim your rc.sysinit
The file /etc/rc.sysinit is very important, it configures core system functions such as mounting local filesystems, activating swap device, setting udev, and so on. Sometimes, you don’t need some of the functions available in rc.sysinit, such as LVM and encrypted filesystem (at least, I don’t). What you can do is removing the “if” statement that calls the function you don’t need. Or better, just comment it out (use “#” in front of the if…fi statement). One example, I don’t use RAID, so why should the system bother to check if I use RAID? Therefore I comment the if statement that contains it.
# If necessary, find md devices and manually assemble RAID arrays
#if [ -f /etc/mdadm.conf -a "$(/bin/grep ^ARRAY /etc/mdadm.conf 2>/dev/null)" ]; then
# # udev won't create these md nodes, so we do it ourselves
# for dev in $(/bin/grep ^ARRAY /etc/mdadm.conf | /bin/awk '{print $2}'); do
# path=$(echo $dev | /bin/sed 's|/[^/]*$||')
# node=$(echo $dev | /bin/sed "s|^$path/||")
# minor=$(echo $node | /bin/sed 's|^[^0-9]*||')
# [ ! -e $path/$node ] && /bin/mknod $path/$node b 9 $minor
# done
# status "Activating RAID arrays" /sbin/mdadm --assemble --scan
#fi
Udev tweaks
Tweak1. We can speedup udev loading time, by starting it earlier in the boot process. If we look at /etc/rc.sysinit we can see this fragment around line 81:
...
stat_busy "Starting UDev Daemon"
/sbin/udevd --daemon
...
and this fragment around line 125:
...
stat_busy "Loading UDev uevents"
...
/sbin/udevadm trigger
/sbin/udevadm settle
...
Let’s move the udev daemon trigger right after the daemon itself is loaded. This will give it some time to finish what it’s doing before getting settled. Also, give the settle command an ampersand so it finishes its job in the background. The finished fragment would look like this:
...
stat_busy "Starting UDev Daemon"
/sbin/udevd --daemon
/sbin/udevadm trigger
...
stat_busy "Loading UDev uevents"
...
/sbin/udevadm settle &
This is like playing catch-up, this is a little bit dangerous since there’s a possibility that a module which is needed not already loaded when a daemon requests access to the particular hardware. This might be the network interface or sound card. But, I haven’t had any problem with this tweak, and I have booted so far without problem.
Tweak 2. Udev, by default, uses it own program to load modules, which is /lib/udev/load_modules.sh. We can improve the modules loading speed of udev by using modprobe instead. Make a copy of load_modules.sh, and then replace it with a symlink to /sbin/modprobe
# cd /lib/udev
# mv load_modules.sh load_modules.sh.backup
# ln -s /sbin/modprobe load_modules.sh
There is one drawback, though. You’ll lose the ability to blacklist modules from rc.conf. Now, you must enter the modules you want blacklisted in /etc/modprobe.conf, which looks like this on my system:
blacklist pcspkr
blacklist soundcore
alias net-pf-10 off
Inittab tweak
We can force the system to immediately load the Virtual Console once the init level is reached. This will enable you to immediately use the Console while the modules are still loaded in the background. We just need to replace “wait” with “once”. It’s much better if autologin feature is enabled (via mingetty). If you’re the only user, why bother logging in? My /etc/inittab looks like this
...
rm:2345 nce:/etc/rc.multi
...
c1:2345:respawn:/sbin/mingetty --autologin prasetya vc/1 linux
...
Optional: Compile a custom kernel
You can compile a kernel that’s suitable for your system, stripping out unneeded stuff and make several device drivers builtin instead modular. This will give you some advantages: Less bloat, and faster booting. Compiling the current kernel is super-easy in Arch Linux. For this, you need ABS (Arch Build System).
# vi /etc/makepkg.conf
# pacman -Syu
# pacman -S abs
# abs
$ cp -R /var/abs/core/kernel26 ~
$ cd ~/kernel26
$ vi config
$ vi PKGBUILD
$ makepkg -i
Step 1 means, edit file /etc/makepkg.conf and add custom CFLAGS according to your CPU type. The list is here. This is to enable CPU specific code optimizations.
Compiling a custom kernel only give me 1 to 2 seconds improvement. It might not quite worth the time wasted on it (about 1+ hour of configuration + compilation), but yeah, I want that extra seconds. And so I give in to the temptation of the dark side . If you decide to upgrade the kernel you’ll lose that optimizations, unless you recompile it with the new code. Given its high maintenance cost it’s only advisable for at least intermediate users (and curious ones). But, if just for kicks, why not? You’ll also learn a thing or two, by the way.
Optional: Recompile the entire system
There’s a script in AUR (Arch User Repository) that enables you to mass-recompile every installed package on your system from source using ABS. This, in logic, will give a more optimized binary for your computer, which in turn will make everything faster. I personally haven’t tried it yet. It’s similar to FreeBSD’s make buildworld/buildkernel command. The script name is pacbuilder, here.
Arch Linux is not originally designed to be mass-recompiled by the user, so the advantages of this script still needs to be proven. I personally wouldn’t want to use this (for now), I’ve had enough of similar process on FreeBSD.
Anyway, you’re bound to recompile each new packages once they hit repo if you use this method. I think it’s cumbersome, if you decided to recompile every new package that is. Anyway, it’s Arch. It’s already very fast. Why bother? But then, it’s up to you.
Other steps
Obviously, you can always improve the overall performance of your system by *upgrading* your system. This solution is the “easiest” and most feasible if you don’t like tweaking and have some $$$ to spend. Go find an extreme series motherboard, put two Quad Core Intel CPUs, buy several SATAII 10K RPM harddisks (or ultra expensive ultra fast SSDs) and put them in raid0+1 config, and buy the fastest, lowest latency memory cards. That’ll cost a fortune, but you’ll be like driving a Lamborghini Reventon (performance wise). Or, just stick to the tweaks .
Conclusion
Why wait for some more seconds while your PC can do it in less? Tweak and refine your system. It’s one part (of many) of computing on Linux that’s very fun in practice, and gives you more knowledge while doing it. |
|