Fast-ish boot for the Arietta

A while ago I posted about cutting the ACME Arietta boot time down from ~30 s to ~4 s. Here’s the hacks I did to get there.

After the kernel has finished initialising it runs ‘init’ which is responsible for setting up the system and starting any services. ‘init’ has the concept of runlevels including runlevel S (initial startup), runlevel 2 (normal operation) and runlevel 6 (reboot). You can configure what init does when it enters a runlevel, including changing it from running a bunch of generic scripts to running a single, specific, and much faster script.

So that’s the trick: change init from executing all of the scripts in /etc/rc2.d/ and instead have it run your own /etc/init.d/rc2.

The first step is to change the init config file /etc/inittab. As a diff:

-l2:2:wait:/etc/init.d/rc 2
+l2:2:wait:/etc/init.d/rc2

Then create a file holding helper functions, including a log function that’s useful when timing individual steps:

/etc/init.d/rc.common:

PATH=/sbin:/usr/sbin:/bin:/usr/bin
export PATH

umask 022

start() {
        echo "+ $@..."
        $@
}

Overwrite the initial startup script /etc/init.d/rcS with:

#!/bin/busybox sh

. /etc/init.d/rc.common

start mount -t proc /proc /proc
start mount -t sysfs /sys /sys
start mount -o remount,rw /
start mount -t tmpfs none /run
mkdir -p /run/network /run/lock

start mount -a
start hostname $(cat /etc/hostname)

#start /etc/init.d/udev start
echo > /sys/kernel/uevent_helper
start udevd --daemon
start udevadm trigger --action=add
start udevadm settle --timeout=0

# PENDING: Load modules.
# PENDING: sysctl
# PENDING: urandom

start ifconfig lo 127.0.0.1 netmask 255.0.0.0 up

and finally create /etc/init.d/rc2 to start your services and perhaps application:

#!/bin/busybox sh

. /etc/init.d/rc.common

make_mac() {
    echo 00$(echo $HOSTNAME $@ | md5sum | cut -b -10)
}

# Ethernet
start modprobe g_ether use_eem=0 dev_addr=$(make_mac dev) host_addr=$(make_mac host)
start ifconfig usb0 192.168.10.10 netmask 255.255.255.0 up

# OpenSSH
mkdir -p /var/run/sshd
chmod 0755 /var/run/sshd
start /usr/sbin/sshd

# Finished!
echo uptime: `cat /proc/uptime`

Make sure the files are executable (chmod +x ...).

The make_mac() function is used to give the USB ethernet gadget a fixed MAC address instead of generating a random one at each boot. This makes setting a static IP address in Chrome OS easier.

Note that I’m using busybox as the shell. It’s really small so should be quick to load and run. Run sudo apt-get install busybox to get it.

Fiddling with init scripts is a good way to break the boot. The easiest way to fix a problem is to put the SD card into your laptop and edit the files directly.

Click here for a tarball of the files.

Avatar
Michael Hope
Software Engineer