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...