Debugging the Alpine boot process
As discussed in my previous post, Alpine Linux goes through several stages when it boots.
Just after mounting the boot media, and scanning it for apkovl’s (with nlplug-findfs), there is an option for you to get a console, by setting $SINGLEMODE to yes.
Setting SINGLEMODE to yes is easy, you simply add the word “single” to the cmdline.txt (if on Raspberry Pi) / your kernel parameters (if not on Raspberry Pi):
modules=loop,squashfs,sd-mod,usb-storage single noquiet dwc_otg.lpm_enable=0 console=tty1
Note that I have also prepended the word quiet with no to effectively disable it – you will get more output during boot. (NB: this is actually the way this is meant to be done, as defined in the init script)
Once you boot, this will drop you into a shell session (with ash, the built-in shell of busybox).
Note: if you have set the root kernel parameter, to specify a root filesystem to boot from, your console is mounted before the root partition is mounted – probably so you can better debug it yourself.
This single mode is very useful for trying boot configurations and debugging boot problems, and experimenting with the system and it’s capabilities (which come entirely from the initramfs and the kernel).
can’t access tty error
The following error is thrown when Single mode is enabled:
sh: can’t access tty: job control turned off
It seems to be related to sh’s capabilities, and how it is executed – no need to be alarmed.
USB keyboard doesn’t work
At first, the USB keyboard didn’t work for me; I am not sure what the reason for this is. After several power cycles it started working. Maybe it can’t be switched in via KVM.
In any case, keep trying, it should work. Try to type immediately when the sh warning comes …
On the Pi 3B+ the keyboard does not work; it only works on a Pi 3A+. I suspect this is due to the additional internal USB Hub on the Pi 3B+ – please try to use a Pi 3A+ to debug in single mode. (I know, not ideal for networking setups).
Is there a shorter way to activate single mode? I am lazy
These are your options:
s|single|1
So you should be able to get into single mode by adding an “s” or a “1” to the cmdline.txt. Not tested by me.
How can I exit singlemode?
Type
exit
What happens after the single mode check?
Our answer refers only to the RAM (“diskless”) boot mode of Alpine Linux.
The following operations are done only after the single mode check, so you will have to run them manually if you want:
- a tmpfs is mounted to /sysroot ($sysroot)
- the apkovl location is set up – per default, if you did not specify the apkovl kernel parameter, nlplug-findfs will have tried to locate it for you on your boot media
- there is, as discussed previously, also the option for you to obtain it via http, etc.
- the pkgs kernel parameter is parsed – you can specify additional packages here, which the system should install
- this parameter is useful in colloboration with alpine_repo – allowing you to inject additional packages into Alpine
- the apkovl is unpacked
- if the file /sysroot/etc/.default_boot_services exists or the apkovl location is not a file, then default boot services will be set up, and the file will be removed (so it will not be persisted in the apkovl when you do lbu commit)
if [ -f “$sysroot/etc/.default_boot_services” -o ! -f “$ovl” ]; then
# add some boot services by default
rc_add devfs sysinit
rc_add dmesg sysinit
rc_add mdev sysinit
rc_add hwdrivers sysinit
rc_add modloop sysinitrc_add hwclock boot
rc_add modules boot
rc_add sysctl boot
rc_add hostname boot
rc_add bootmisc boot
rc_add syslog bootrc_add mount-ro shutdown
rc_add killprocs shutdown
rc_add savecache shutdownrc_add firstboot default
rm -f “$sysroot/etc/.default_boot_services”
fi
- code for executing a splash screen is run
- it is checked whether /sysroot/etc/fstab exists, and conditionally on that relocate_mount is executed
- alpine-base is always included in the packages which are going to be installed
- apk is prepared
- optionally networking is configured so apk can pull the packages through the network
- it is also told that the packages are being installed in –initramfs-diskless-boot mode, and told to display –progress
- if quiet is set, then apk is told to stay –quiet
- packages are installed to the root filesystem
- if the kernel option ssh_key is given, openssh is added to the packages and as a service
- please note that you still need to pass in the key – this will happen either through a file in your apkovl or some other method
- as such, the option ssh_key might be a kind of fallback if you have turned off ssh and want it back again.
- finally the root is switched into the new system which is built from the packages and the apkovl
Note, for anyone wondering what the keep_apk_new kernel parameter is supposed to do:
if [ “$KOPT_keep_apk_new” != yes ]; then
apkflags=”$apkflags –clean-protected”
[ -n “$ovlfiles” ] && apkflags=”$apkflags –overlay-from-stdin”
fi
Please refer to the init file in the initramfs for further details.
References:
- https://ss64.com/bash/test.html Useful page to understand the init file better (scripting in ash / bash)
We’re for hire
If you are looking to solve your Alpine Linux problem, and want consulting we are for hire.