In my Raspberry Pi + Hifiberry-amp + Pitft project I’ve been looking how to speed up the boot process.
[edit] I updated various parts of this post with suggestions from the comments. [/edit]
The original boot process took around 60 seconds from “power on” until my gtk app was visible and responding. I used the original (Wheezy based) raspbian, with autologon on tty1, and in the .bash_profile I called startx. In /home/pi/.xinitrc I started my application without starting a display manager:
#!/bin/sh
PYTHONIOENCODING=utf_8
export PYTHONIOENCODING
exec /usr/bin/python /home/pi/sqgui2.py
(b.t.w. the PYTHONIOENCODING is there otherwise python will give an exception when calling print with a non-ascii unicode character)
By removing a few services from the init process I removed 10 seconds from the boot process. Still 50 seconds. But further options on Raspbian Wheezy are limited.
Next step was to move to Raspbian Jessie, which has systemd. This gave an unwanted side effect: the hifiberry was detected correctly, but did not produce any sound anymore. Removing a line added for the pitft device_tree=bcm2708-rpi-b-plus.dtb
from /boot/config.txt fixed this problem. And the pitft is still working.
In systemd I can start X11 as soon as userspace is running. However this generated an error – the touchscreen device has to be available first. The touchscreen input is in udev configured as /dev/input/touchscreen. I created /etc/systemd/system/xinit-login.service with the following content:
[Unit]
Wants=dev-input-touchscreen.device
After=dev-input-touchscreen.device
DefaultDependencies=false
[Service]
Type=simple
ExecStart=/bin/su pi -l -c /usr/bin/xinit -- VT08
WorkingDirectory=/home/pi/
[Install]
WantedBy=local-fs.target
[edit] with suggestions from the comments in now looks like:
[Unit]
Wants=dev-input-touchscreen.device
After=dev-input-touchscreen.device
DefaultDependencies=false
[Service]
Type=simple
ExecStart=/usr/bin/xinit
WorkingDirectory=/home/pi/
User=pi
Group=Users
Environment=PYTHONIOENCODING=utf_8
[Install]
WantedBy=local-fs.target
and .xinitrc is now a hardlink to the gtk application sqgui.py [/edit]
This makes my xinit session start directly after the touchscreen device is available. This reduced the startup time to 28 seconds. Much better! (b.t.w. I haven’t look if all entries in xinit-login.service are correct, perhaps the contents can be improved).
Systemd has a good tool called systemd-analyze which analyzes the boot process. That way you can easily see which parts take too much time. That helped me to strip off another 2 seconds. An interesting question is how the udev config can be improved to create the touchscreen device earlier in the boot process. Another interesting question is how X11 can be configured to start faster, or how python + gtk3 can be configured to start faster. If you have any suggestions please leave them in the comments.
Next thing was to make the system readonly. I installed busybox-syslogd instead of rsyslogd, since it can do in-memory logging. [edit] I now switched to systemd-journald for in memory logging [/edit]
I analyzed which directories changed after a reboot, and moved those to a tmpfs in-memory filesystem. The /etc/fstab now looks like:
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults,ro 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime,ro 0 1
tmpfs /tmp tmpfs defaults,noatime 0 0
tmpfs /var/lock tmpfs defaults,noatime 0 0
tmpfs /var/lib/dhcpcd5 tmpfs defaults,noatime 0 0
tmpfs /var/log tmpfs defaults,noatime 0 0
Possibly this can be optimized with a single tmpfs mount and symlinks to reduce the mount time of 4 tmpfs filesystems.
[edit] did that, they are all symlinks to /tmp now [/edit]
The only remaining issue that I didn’t solve yet is handling of /etc/resolv.conf when moving the setup to a different network. Because /etc/ is readonly the resolv.conf is now fixed for my local wifi network.
[edit] disabling the UART, and moving from the debian networking scripts to systemd-networkd reduced the boot time to 21 seconds! [/edit]