Demystify GNU/Linux boot process with Systemd

2842

The boot process in Systemd

Basically there to ways of booting GNU/Linux the initramfs way or using a disk partition specifier in your kernel configuration. I won’t explain how the later works but you can specify the root device as a kernel parameter eg. in grub like root=/dev/sda1 or whatever fits your systems root partition. The good thing about initrd images it is a filesystem residing in your RAM and it contains just what you specify. From kernel modules, to binaries and for sure a init script.

It starts with a kernel

Linux can be build with drivers as loadable modules. First of all we start with a clean kernel source tree. Then you may configure the kernel features and drivers. You can navigate with Up and Down, show informations with ? or toggle with <Space>. Linux kernel configuration allows you to load a template file. Me, I prefere using debian style kernel configuration. Note you should immediately save the template as .config

# make mrproper
# make menuconfig

Now we are ready to build the linux image. After we install the kernel modules in /lib/modules/<kernel-version>. Then we copy the kernel to /boot directory. It is assumed the kernel to be x86_64 architecture compatible.

# make -j5
# make modules_install
# cp -v arch/x86_64/boot/bzImage /boot/vmlinuz-<kernel-version>

About initrd images

The initramfs are usually compressed the kernel supports various compression formats. As prior mentioned you might want to put in kernel modules available in early boot stage or certain binaries like `switch_root` to change root fs from initird image to your HDD. A final call to `init` is performed in order to systemd to overtake the control of boot process. The mkinitramfs script takes as parameter the kernel version and generates an initrd image for you. You should invoke it in the /boot directory as root.

# mkinitramfs <kernel-version>

The compatibility layer to Sys-V

The most comfortable thing about Systemd is its compatibility layer to system five. That’s why I’m telling you what is not systemd. /etc/inittab, /etc/rc.d and /etc/init.d are all related to Sys-V.

Service and target files

In Systemd every command is cabaple running as service. These services can be launched by the systemd message bus and are described by a .service file. Common places for those files are either /lib/systemd/system or /usr/lib/systemd/system.

Here is a sample file from my system /lib/systemd/system/systemd-logind.service. The most important key is ExecStart=/lib/systemd/systemd-logind from Service section. It tells systemd what command to launch. In this case it starts the Systemd login manager.


#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Login Service
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
Wants=user.slice
After=nss-user-lookup.target user.slice

# Ask for the dbus socket. If running over kdbus, the socket will
# not be actually used.
Wants=dbus.socket
After=dbus.socket

[Service]
ExecStart=/lib/systemd/systemd-logind
Restart=always
RestartSec=0
BusName=org.freedesktop.login1
CapabilityBoundingSet=CAP_SYS_ADMIN CAP_MAC_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CAP_KILL CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_FOWNER CAP_SYS_TTY_CONFIG
WatchdogSec=1min

# Increase the default a bit in order to allow many simultaneous
# logins since we keep one fd open per session.
LimitNOFILE=16384

The .target files specifies prerequisites when a goal of the target has been accomplished. So Systemd can proceed with further targets. Targets can have After and Before prerequisites of targets or services. Here’s a sample .target file /lib/systemd/system/multi-user.target.

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

A true multi-user system

The file /lib/systemd/system/systemd-user-sessions.service could look like following. Please consider `man systemd-user-sessions` in order to get understanding of ExecStart and ExecStop.

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Permit User Sessions
Documentation=man:systemd-user-sessions.service(8)
After=remote-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/lib/systemd/systemd-user-sessions start
ExecStop=/lib/systemd/systemd-user-sessions stop

You might want to enable or disable services with the `systemctl` command. To enable root only logins issue the following:

# systemctl disable systemd-user-sessions