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.