Tweaking for a faster boot time
From ArchWiki
Contents |
Summary
This is the result of 2 days of tweaking for a faster boot time.
Why: just because you can, for other people to see what is possible with Arch Linux.
See the forumtopic, the scripts may differ from the one in the topic because of further tweaking.
Grub to agetty in 13s (coming from 24s) on a Dell Inspiron 1525 (Core2Duo T5450 1,66 Ghz) (bootcharts in same forumtopic)
/etc/inittab
This will not increase the speed that much, but every little bit helps.
# # /etc/inittab # # Boot to console id:3:initdefault: # Use once instead of wait rc::sysinit:/etc/rc.sysinit rs:S1:once:/etc/rc.single rm:2345:once:/etc/rc.multi rh:06:once:/etc/rc.shutdown su:S:once:/sbin/sulogin -p #Start lesser agetty's and login from agetty c1:2345:respawn:/sbin/agetty -8 38400 vc/1 linux c2:2345:respawn:/sbin/agetty -8 38400 vc/2 linux ca::ctrlaltdel:/sbin/shutdown -t3 -r now # End of file
Alternatively instead of using agetty, use fgetty which is smaller and fast by replacing:
c1:2345:respawn:/sbin/agetty -8 38400 vc/1 linux
with
1:23:respawn:/sbin/fgetty tty1
/etc/mkinitcpio.conf
This didn't really speed up my boot, but on some systems it does.
This didn't work for me on Kernel 2.6.27 and needed to put Udev back in HOOKS, never tried to figure out why it didn't work. I tried again when installing kernel 2.6.28 and that did work. If you use a USB keyboard, add 'usbinput' in HOOKS
My boot device was a separate partion on a SATA drive formatted as ext3. I needed to enable AHCI in my BIOS, before this it used a ATA module.
# # /etc/mkinitcpio # #Load necessary modules to mount boot device MODULES="ahci sd-mod ext3" BINARIES="" FILES="" HOOKS="base" # End of file
/etc/rc.sysinit
Here I had the most work, and gained the most speed.
I took out the stuff I didn't use: LVM, RAID and Encrypted devices.
Including default behavior for the clock, LOCALE, KEYMAP and HOSTNAME directly into this file, so it doesn't have to load it from #/etc/rc.conf.
I've added a lot of ampersands to send these processes to the background. Watch out with what you send to the background, because otherwise later commands that depend on the backgrounded process might be called before the process is running. The first time '/sbin/hwclock' and '/sbin/udevadm settled' are called are examples of that.
Also I've put '/sbin/udevadm trigger &' earlier and in background, so it had the time to load until '/sbin/udevadm settled' is called.
Putting in 'status "Updating Module Dependencies" /sbin/depmod -A' in comment requires you to run it when you install new modules. It is not a required for boot, so I don't know what it does there in first time.
#!/bin/bash
#
# /etc/rc.sysinit
#
. /etc/rc.conf
. /etc/rc.d/functions
echo " "
printhl "Arch Linux\n"
printhl "${C_H2}http://www.archlinux.org"
printhl "Copyright 2002-2007 Judd Vinet"
printhl "Copyright 2007-2008 Aaron Griffin"
printhl "Distributed under the GNU General Public License (GPL)"
printsep
# mount /proc, /sys and our RAM /dev
/bin/mount -n -t ramfs none /dev
/bin/mount -n -t proc none /proc
/bin/mount -n -t sysfs none /sys
# Create our default nodes that minilogd may need
/bin/mknod /dev/null c 1 3
/bin/mknod /dev/zero c 1 5
/bin/mknod /dev/console c 5 1
# More initial /dev setup that udev doesn't do
/bin/ln -snf /proc/self/fd /dev/fd
/bin/ln -snf /proc/self/fd/0 /dev/stdin
/bin/ln -snf /proc/self/fd/1 /dev/stdout
/bin/ln -snf /proc/self/fd/2 /dev/stderr
/bin/ln -snf /proc/kcore /dev/core
/bin/mkdir /dev/pts
/bin/mkdir /dev/shm
# start up our mini logger until syslog takes over
/sbin/minilogd
# anything more serious than KERN_WARNING goes to the console
# 'verbose' cmdline parameter enables more messages
if /bin/grep -q " verbose" /proc/cmdline; then
/bin/dmesg -n 8
else
/bin/dmesg -n 3
fi
# enable rtc access
/sbin/modprobe rtc-cmos >/dev/null 2>&1
RTC_MAJOR=$(/bin/grep -w rtc /proc/devices 2>/dev/null); RTC_MAJOR="${RTC_MAJOR%% *}"
if [ -n "$RTC_MAJOR" ]; then
/bin/mkdir /dev/misc/
/bin/mknod /dev/misc/rtc0 c $RTC_MAJOR 0
/bin/ln -s /dev/misc/rtc0 /dev/rtc
fi
# Set clock early to fix some bugs with filesystem checks
# Clock is set again later to match rc.conf
if [ -f /etc/localtime ]; then
/sbin/hwclock --hctosys --localtime --directisa --noadjfile
fi
echo > /proc/sys/kernel/hotplug
if [ -x /sbin/udevadm -a -d /sys/block ]; then
# We have udev and /sys appears to be mounted, use UDev
stat_busy "Starting UDev Daemon"
/sbin/udevd --daemon
/sbin/udevadm trigger &
udevstart="$(/bin/date +%s%0N)"
stat_done
else
# Static /dev, our last resort
status "Using static /dev filesystem" true
fi
# Load modules from the MODULES array defined in rc.conf
if ! [ "$load_modules" = "off" ]; then
if [ -f /proc/modules ]; then
stat_busy "Loading Modules"
for mod in "${MODULES[@]}"; do
if [ "$mod" = "${mod#!}" ]; then
/sbin/modprobe $mod &
fi
done
stat_done
fi
if [ -d /proc/acpi ]; then
stat_busy "Loading standard ACPI modules"
ACPI_MODULES="ac battery button fan processor thermal"
k="$(echo $BLACKLIST ${MOD_BLACKLIST[@]} | /bin/sed 's|-|_|g')"
j="$(echo ${MODULES[@]} | /bin/sed 's|-|_|g')"
#add disabled MODULES (!) to blacklist - much requested feature
for m in ${j}; do
[ "$m" != "${m#!}" ] && k="${k} ${m#!}"
done
# add disablemodules= from commandline to blacklist
k="${k} $(echo ${disablemodules} | /bin/sed 's|-|_|g' | /bin/sed 's|,| |g')"
for n in ${ACPI_MODULES}; do
if ! echo ${k} | /bin/grep "\<$n\>" 2>&1 >/dev/null; then
/sbin/modprobe $n > /dev/null 2>&1 &
fi
done
stat_done
fi
fi
# run udev uevents
if /bin/pidof -o %PPID /sbin/udevd >/dev/null; then
stat_busy "Loading UDev uevents"
/sbin/udevadm settle
stat_done
udevend="$(/bin/date +%s%0N)"
printhl " UDev uevent processing time: $((($udevend-$udevstart)/1000000))ms"
fi
# bring up the loopback interface
if [ -d /sys/class/net/lo ]; then
stat_busy "Bringing up loopback interface"
/sbin/ifconfig lo 127.0.0.1 up &
if [ $? -ne 0 ]; then
stat_fail
else
stat_done
fi
fi
status "Mounting Root Read-only" /bin/mount -n -o remount,ro /
FORCEFSCK=
[ -f /forcefsck ] && FORCEFSCK="-- -f"
NETFS="nonfs,nonfs4,nosmbfs,nocifs,nocodafs,noncpfs,nosysfs,noshfs,nofuse,nofuseblk"
if [ -x /sbin/fsck ]; then
stat_busy "Checking Filesystems"
if /bin/grep -qw quiet /proc/cmdline; then
/sbin/fsck -A -T -C -a -t $NETFS $FORCEFSCK >/dev/null 2>&1
else
/sbin/fsck -A -T -C -a -t $NETFS $FORCEFSCK 2>/dev/null
fi
fsckret=$?
if [ ${fsckret} -gt 1 ]; then
stat_fail
if [ $((${fsckret}&2)) -eq 2 ]; then
echo
echo "********************** REBOOT REQUIRED *********************"
echo "* *"
echo "* The system will be rebooted automatically in 15 seconds. *"
echo "* *"
echo "************************************************************"
echo
/bin/sleep 15
else
echo
echo "***************** FILESYSTEM CHECK FAILED ****************"
echo "* *"
echo "* Please repair manually and reboot. Note that the root *"
echo "* file system is currently mounted read-only. To remount *"
echo "* it read-write type: mount -n -o remount,rw / *"
echo "* When you exit the maintenance shell the system will *"
echo "* reboot automatically. *"
echo "* *"
echo "************************************************************"
echo
/sbin/sulogin -p
fi
echo "Automatic reboot in progress..."
/bin/umount -a
/bin/mount -n -o remount,ro /
/sbin/reboot -f
exit 0
fi
stat_done
fi
stat_busy "Mounting Local Filesystems"
/bin/mount -n -o remount,rw /
/bin/rm -f /etc/mtab*
# make sure / gets written to /etc/mtab
/bin/mount -o remount,rw /
# Write /proc, /sys and /dev to /etc/mtab
if [ -e /proc/mounts ]; then
/bin/grep -e "/proc " -e "/sys " -e "/dev " /proc/mounts >> /etc/mtab
fi
# now mount all the local filesystems
/bin/mount -a -t $NETFS
stat_done
status "Activating Swap" /sbin/swapon -a &
stat_busy "Configuring System Clock"
if [ ! -f /var/lib/hwclock/adjtime ]; then
echo "0.0 0 0.0" > /var/lib/hwclock/adjtime &
fi
/bin/rm -f /etc/localtime
/bin/cp "/usr/share/zoneinfo/Europe/Brussels" /etc/localtime
/sbin/hwclock --hctosys --localtime --directisa
stat_done
if [ -f /var/run/random-seed ]; then
stat_busy "Initializing Random Seed"
/bin/cat /var/run/random-seed >/dev/urandom &
stat_done
fi
stat_busy "Removing Leftover Files"
/bin/rm -f /etc/nologin &>/dev/null &
/bin/rm -f /etc/shutdownpid &>/dev/null &
/bin/rm -f /var/lock/* &>/dev/null &
/bin/rm -rf /tmp/* /tmp/.* &>/dev/null &
/bin/rm -f /forcefsck &>/dev/null &
(cd /var/run && /usr/bin/find . ! -type d -exec /bin/rm -f -- {} \; )
: > /var/run/utmp &
# Keep {x,k,g}dm happy with xorg
/bin/mkdir /tmp/.ICE-unix && /bin/chmod 1777 /tmp/.ICE-unix
/bin/mkdir /tmp/.X11-unix && /bin/chmod 1777 /tmp/.X11-unix
stat_done
#status "Updating Shared Library Links" /sbin/ldconfig
#status "Updating Module Dependencies" /sbin/depmod -A &
status "Setting Hostname: Pinguin" /bin/hostname "Pinguin" &
# Flush old locale settings
: >/etc/profile.d/locale.sh
/bin/chmod 755 /etc/profile.d/locale.sh
# Set user defined locale
[ -z "$LOCALE" ] && LOCALE="en_US"
stat_busy "Setting Locale: en_US"
echo "export LANG=en_US" >>/etc/profile.d/locale.sh
stat_done
stat_busy "Setting Consoles to UTF-8 mode"
# UTF-8 consoles are default since 2.6.24 kernel
# this code is needed not only for older kernels,
# but also when user has set vt.default_utf8=0 but LOCALE is *.UTF-8.
for i in $(/usr/bin/seq 0 63); do
usr/bin/kbd_mode -u < /dev/vc/${i}
printf "\e%%G" > /dev/vc/${i}
done
# the $CONSOLE check helps us avoid this when running scripts from cron
echo 'if [ "$CONSOLE" = "" -a "$TERM" = "linux" -a -t 1 ]; then printf "\e%%G"; fi' >>/etc/profile.d/locale.sh
stat_done
status "Loading Keyboard Map: be-latin1" /bin/loadkeys -q -u "be-latin1" &
# Adding persistent network/cdrom generated rules
if [ -f "/dev/.udev/tmp-rules--70-persistent-cd.rules" ]; then
stat_busy "Adding persistent cdrom udev rules"
/bin/cat /dev/.udev/tmp-rules--70-persistent-cd.rules >> /etc/udev/rules.d/70-persistent-cd.rules
stat_done
fi
if [ -f "/dev/.udev/tmp-rules--70-persistent-net.rules" ]; then
stat_busy "Adding persistent network udev rules"
/bin/cat /dev/.udev/tmp-rules--70-persistent-net.rules >> /etc/udev/rules.d/70-persistent-net.rules
stat_done
fi
# Save our dmesg output from this boot
if [ -f /var/log/dmesg.log ]; then
/bin/rm /var/log/dmesg.log
fi
/bin/dmesg > /var/log/dmesg.log &
# End of file
/etc/rc.conf
I've stripped out everything here that I included by default in #/etc/rc.sysinit and #/etc/rc.shutdown.
In this version the modules I need for my laptop are in the MODULES array, so there is no need to turn MOD_AUTOLOAD on. I could strip out some modules, but didn't find the time to figure that out. The list I got from 'hwdetect --show-modules-order'. I did take out snd-hda-codec and dock, because these gave an error on load.
# # /etc/rc.conf # MOD_AUTOLOAD="no" MODULES=(ac battery button processor thermal video wmi agpgart intel-agp dcdbas hid usbhid i2c-i801 i2c-core evdev ff-memless joydev pcspkr psmouse serio_raw led-class mmc_core ricoh_mmc sdhci-pci sdhci rtc-cmos rtc-core rtc-lib output iTCO_vendor_support iTCO_wdt snd-mixer-oss snd-pcm-oss snd-hwdep snd-page-alloc snd-pcm snd-timer snd snd-hda- intel soundcore pata_acpi ata_generic ahci ata_piix sky2 mac80211 rfkill usb-storage usbhid usbcore ehci-hcd uhci-hcd vboxdrv vboxnetflt) DAEMONS=(syslog-ng @hal @fam @crond @alsa) # End of file
In this version the modules are discovered by the system itself. I guess this is the smallest a usable /etc/rc.conf can get.
MOD_AUTOLOAD="yes" MODULES=() DAEMONS=(syslog-ng @hal @fam @crond @alsa)
/etc/rc.shutdown
This doesn't have anything to do with the boot time, but with #/etc/rc.conf. By stripping out a lot out, I broke the shutdown script. In meanwhile I've taken out the unnecessary stuff (LVM, ...).
#!/bin/bash
#
# /etc/rc.shutdown
#
. /etc/rc.conf
. /etc/rc.d/functions
# avoid staircase effect
/bin/stty onlcr
echo " "
printhl "Initiating Shutdown..."
echo " "
# avoid NIS hanging syslog-ng on shutdown by unsetting the domainname
if [ -x /bin/domainname ]; then
/bin/domainname ""
fi
if [ -x /etc/rc.local.shutdown ]; then
/etc/rc.local.shutdown
fi
if [ "$PREVLEVEL" = "3" -o "$PREVLEVEL" = "5" ]; then
# Shutdown daemons
let i=${#DAEMONS[@]}
while [ $i -ge 0 ]; do
if [ "${DAEMONS[$i]:0:1}" != '!' ]; then
ck_daemon ${DAEMONS[$i]#@} || stop_daemon ${DAEMONS[$i]#@}
fi
let i=i-1
done
# find any leftover daemons and shut them down in reverse order
if [ -d /var/run/daemons ]; then
for daemon in $(/bin/ls -1t /var/run/daemons); do
stop_daemon $daemon
done
fi
fi
# Terminate all processes
stat_busy "Sending SIGTERM To Processes"
/sbin/killall5 -15 &> /dev/null
/bin/sleep 5
stat_done
stat_busy "Sending SIGKILL To Processes"
/sbin/killall5 -9 &> /dev/null
/bin/sleep 1
stat_done
stat_busy "Saving Random Seed"
/bin/dd if=/dev/urandom of=/var/run/random-seed count=1 bs=512 2> /dev/null
stat_done
stat_busy "Saving System Clock"
/bin/rm -f /etc/localtime
/bin/cp "/usr/share/zoneinfo/Europe/Brussels" /etc/localtime
/sbin/hwclock --systohc --localtime --directisa
stat_done
# removing psmouse module to fix some reboot issues on newer laptops
/sbin/modprobe -r psmouse >/dev/null 2>&1
# Write to wtmp file before unmounting
/sbin/halt -w
stat_busy "Deactivating Swap"
/sbin/swapoff -a
stat_done
stat_busy "Unmounting Filesystems"
/bin/umount -a -r -t noramfs,notmpfs,nosysfs,noproc
stat_done
stat_busy "Remounting Root Filesystem Read-only"
/bin/mount -n -o remount,ro /
stat_done
# Power off or reboot
if [ "$RUNLEVEL" = "0" ]; then
printsep
printhl "${C_H2}POWER OFF"
/sbin/poweroff -d -f -h -i
else
printsep
printhl "${C_H2}REBOOTING"
# if kexec is installed and a kernel is loaded, use it
[ -x /sbin/kexec ] && /sbin/kexec -e > /dev/null 2>&1
/sbin/reboot -d -f -i
fi
# End of file
/lib/udev/load-modules.sh
Something little, but improving, here. It takes away the blacklisting function for the MODULES array in #/etc/rc.conf, but when MOD_AUTOLOAD off it's not used either way.
Check Speedup_udev#Blacklisting_modules if you need blacklisting. I got this tweak from the same page, there are other ways to do this on there.
#!/bin/sh # # /lib/udev/load-modules.sh # /sbin/modprobe $1 & # End of file
Additional Resources
- The Arch boot process
- Fast boot without recompiling the kernel
- Udev
- Speedup udev
- Daemons
- Rc.conf
- Configuring mkinitcpio
- http://bbs.archlinux.org/search.php - a lot of searching :D
- http://kmandla.wordpress.com/howtos/ - some great howtos
- Sreadahead Google code project (A AUR package for speeding up the boot process dramatically).
- And others...