Booting the Kernel

The bootloader as Grub loads the kernel. The kernel is the extracting itself and starts itself.

If something goes wrong the kernel stops with a panic messages. Sometimes the kernel hangs. I this case it is worth to wait, maybe it is just a blocker and the kernel continuous after a while (e.g. after 1 min). If the system comes up, dmesg will show the trouble and its first column is the time, so the hanger can easily be found.

When the kernel comes up in a traditionally SysVinit system it starts /sbin/init. Grub can be configured to let the kernel start any other program than init. Some newer Linux systems have replaced init by the newer systemd. On those system /usr/lib/systemd/systemd will be called instead.

To get a nice boot sequence seeing one tux per processor, you need to enable framebuffer support in the kernel, select therefore VESA VGA graphics and Framebuffer Console support.


SysVinit makes uses init and init reads /etc/inittab and executes the scripts in /etc/init.d accordingly. Since this configuration is very flexible and can be easy adapted many versions of the scripts exist. This is one of the main differences between the different Linux distributions. The following is based on the scripts OpenRC uses. OpenRC is what uses init on a Gentoo Linux system.


Openrc makes use of c programs and allows that script can run in parallel. See: .

The configuration is in /etc/rc.conf. It can create a log file (optionally verbose) in /var/log/rc.log, however during booting no writable file-system might be available and therefore the logger might create an error. A way out might be specify an other path than /var/log as setting up an initial ram disk.

A option exist and set by default to interrupt the boot process by pressing the I key.

/etc/conf.d/modules holds the kernel modules to be loaded.


As default the Linux kernel starts the program init as first process.

init is a regular program see man init. init reads the file /etc/inittab that has a list of instructions for init.

There are usually 7 runlevels (0 to 6). A runlevel is a mode of operation defined in /etc/inittab.

The program init can also be called when Linux is running to change the runlevel.

The command init 0 changes to runlevel halt and turns off the computer.

The command init 6 causes a reboot.

The program init creates the binary log files /var/run/utmp and /var/log/wtmp.

The file /etc/inittab contains individual lines having the following structure:

idcode: runlevel: action: command

  1. The idcode has to be an unique 2 character string.

  2. The runlevel is a number 0 to 6 or a list of runlevel numbers indicating on what runlevels the line has to be interpreted.

  3. The action field defines the purpose of the line (initdefault, ctrlaltdelete, once, respawn, sysinit, wait)

  4. Finally the command is the command executed in the way the line defines it (runlevel and action). As any command the command can also have command line arguments.

The contents of /etc/inittab is Linux distribution depending. In Gentoo /etc/inittab is configured that the script /sbin/rc is called with various script parameters (shutdown, boot, sysinit).

Traditional distributions made use of simple bash scripts for the purpose of rc. This is more open, but has some limitations. Gentoo uses the bash script rc script, however it does not use bash directly it uses /sbin/runscript. runscript is a program written in c that calls (also in /sbin) both are part of Gentoo's baselayout, both form a initscript handler that calls bash. As root type runscript help. The source of the c program runscript is delivered inside baselayout-<version>.tar.bz2 that can be found in /usr/portage/distfiles when not present download it from There are many copies of runscript on the pc:

whereis runscript

runscript: /usr/bin/runscript /sbin/runscript /usr/share/man/man1/runscript.1.bz2 /usr/share/man/man8/runscript.8.bz2

The /usr/sbin/runscript will be taken at boot as seen by the PATH environmental variable:

echo $PATH


or found by which:

which runscript


To see from where all the other runscripts are coming from:

qfile /usr/bin/runscript

net-dialup/minicom (/usr/bin/runscript)

Or all in one command

qfile $(whereis runscript)

sys-apps/openrc (/usr/share/man/man8/runscript.8.bz2)

sys-apps/openrc (/sbin/runscript)

net-dialup/minicom (/usr/share/man/man1/runscript.1.bz2)

net-dialup/minicom (/usr/bin/runscript)

The script interpreter for minicom is also called runscript, but is a completely different program. If the path and which would point to this binary, then the system would no more to be able to boot!

To see what init is doing, runscript.c can be hacked. Copy baselayout somewhere and go into the /src directory. There modify the main by putting some print statements:

        int main(int argc, char *argv[])
int debugcounter;
printf("\033[33mDebug support in runscript, %i command line parameters\n",argc);

Save the file and run make in this directory, now backup the runscript in /sbin and copy over the new runscript. Now when you boot or do a shutdown, you can observe how init is calling rc and how the /etc/init.d routines are called. This is a temporary hack and will be wiped off when you do a re-emerge baselayout, or just copy over the saved runscript.

The hack could be expanded to debug further the rc scripts! It would be nice to have something as this not as hack, but as official baselayout feature!

Improving the boot time

The /sbin/init boots one service after an other. This is quite robust and reliable but not very fast. The PC waits e.g. for a IP address from the DHCP server and continues just after having it receive. Instead of waiting it could initialize other hardware and do other things.

You could work with static IP addresses to avoid waiting for DHCP.

To get some other slight optimization there is also an option in the /etc/conf.d/rc


However the bootup messages are drastically reduced and you will not easily see if the system has a problem.

There is also the kernel parameter fastboot that can be added to the grub

        title=Gentoo Linux fastboot 2.6.36-gentoo-r5-2010-12-27
root (hd0,0)
kernel /kernel-2.6.36-gentoo-r5-2010-12-27 root=/dev/sda2 vga=0x31B fastboot

Mounting the file systems

init is also responsible to read /etc/fstab and mount the file system. In fact this is one of the first action it does. However it does this not automatically, it reads this out of /etc/inittab

        si::sysinit:/sbin/rc sysinit

Boot script and default runlevel

After having mounted the file systems, init reads from /etc/inittab to start the bootscripts:

        rc::bootwait:/sbin/rc boot

after this the default runlevel 3 is read from /etc/inittab


Then all scripts and login shells from this runlevel are started.


/etc/init.d holds all the scripts that init starts. Which boot scripts start depends on the users needs and runlevels. The rc-update program finally configures what scripts in /etc/init.d have to run and when. Type rc-update -s to get the view of the situation. The configuration is stored in /etc/runlevels where every runlevel has a directory and those directories have links to the scripts in /etc/init.d.

The scripts can also be started, stopped or restarted

/etc/init.d/ntpd stop

/etc/init.d/ntpd start

/etc/init.d/ntpd restart

What init handles can be see by

rc-update -s or full command rc-update show

The /etc/init.d scripts can be linked to init by

rc-update add lircd default

rc-update del lircd

Other useful commands:

rc-status boot

rc-status default

rc-status -a

The command runlevel shows preceding and actual runlevel.

Additional runlevels can be added and even be selected on boot time telling grub to pass a parameter via kernel to init. The runlevel offline can be used with the keyword softlevel (or bootlevel) on a laptop to give an alternative to not start the network.

        title Gentoo Linux Offline Usage
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline

The scripts make use of their configuration data found under /etc/conf.d The file /etc/conf.d/local.start is a bit special since commands can be put there that will be started on boot. A cleaner way is writing boot scripts for /etc/init.d

Writing OpenRC scripts

Once OpenRC was a project on its own, but it became an orphaned so Gentoo took it over. Unfortunately the documentation is now a bit vague, The fact that many Linux distributions move away from SysVinit to systemd gives not much hope that the documentation improves. Reverse engineering from scripts under /etc/init.d as ntpd and ntp-client is a way to go however a good documentation can also be found at

Just on script is required to start and stop the daemons, it should look as follows


The depend function can have keywords as need,use, before and after and allows to set a startup sequence.

  need apache2

The start function starts the daemon using the start-stop-daemon function (see man start-stop-daemon) with all options as desired

  ebegin "starting my daemon"
  start-stop-daemon --background --start --exec <daemon> \ 
  --make-pidfile --pid-file /var/run/<pid file>.pid
  eend $?

Creating a pid file is optional but helps OpenRC to find the process number and to stop the script when desired.

The stop function then could look as

  ebegin "stop my daemon"
  start-stop-daemon --stop --exec daemon \ 
  --pid-file /var/run/pid
  eend $?

Login at startup

Additionally /etc/inittab is responsible for the login. Historically there was one UNIX computer that had many terminals connected via RS232 to it. Now this is emulated with different console windows (getty). The agetty lines define such a virtual terminal with the virtual baudrate of 28400.

        c1:12345:respawn:/sbin/agetty 38400 tty1 linux

Or if you really want to log in via RS232

        #s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100

There is also mingetty that allows automatic login of users without password. Just emerge mingetty and put a line as

        1:3:respawn:/sbin/mingetty --autologin <USER> tty1

to replace agetty and it parameters.


systemd is a replacement for sysvinit. Unfortunately there is a lot of controversy about it but finally it has made it in most of the Linux distributions as default start up method.

Some links: or the original German version,

Using systemd makes the different Linux distributions very similar. What stays different is the package handling and management.

/etc/mtab is handled differently since systemd does mounting. For backward compatibility do or check ln -sf /proc/self/mounts /etc/mtab

systemd does not require a udev package since it includes it (this has put the pressure to distributions using OpenRC to fork udev in a separate package).

systemd replaces ConsoleKit

Dealing with /etc/fstab additional .mount and .swap units can be automatically created


can be added to the drives in /etc/fstab to convert them to automount drives and not have the system waiting until such typically network drives are ready.

Since systemd is running all the time also a gui tool systemadm is available.

systemd-analyze tells how long the boot process was taking

There is support to make a svg graphics as bootchart systemd-analyze plot > plot.svg or systemd-analyze dot | dot -Tsvg > systemd.svg to convert it first to dot format and then having dot making the dependengy graph. Or simply see the ranking of what took long to start systemd-analyze blame

Keyboard layout can be listed as localectl list-keymaps and loaded as root with loadkeys <keymap as sg> or persistent by localectl set-keymap --no-convert <keymap> this modifies /etc/vconsole.conf obviously /etc/vconsole.conf could also be edited using an editor.

systemctl poweroff turns off the computer and systemctl reboot reboots it. More precise systemctrl calls the unit that is in /usr/lib/systemd/system

Modules not loaded automatically can be listed (one per line) and added to files like /etc/modules-load.d/<some name>.conf

The network must probably be started. In case of dhcp start the client daemon dhcpcd eth0 or start it via its unit systemctl start dhcpcd@eth0.service

Boot with systemd

The kernel must know to start systemd and not init after it has booted. For grub legacy put

        kernel /vmlinuz root=/dev/sda2 init=/usr/lib/systemd/systemd

in /boot/grub/grub.conf and for grub 2 put


in /etc/default/grub

Systemd units

The units are text files and have different file extensions as

  • .service to start a service (e.g a daemon)

  • .mount to mount a filesystem (there is also .automount)

  • .socket prepare a socket for a listener and when accessed trigger an action

  • .path to monitor accesses to a file or directory and trigger an action

systemd handle services as known from sysvinit systems:

systemctl start <name>.service starts a service

systemctl stop <name>.service stops a service

systemctl restart <name>.service stops and then starts a service

systemctl reload <name>.service similar to restart is reload however normal functionality of the service keeps maintained.

sysemctl status <name>.service shows the status

systemctl cat <name>.service to read the file without dealing with its path

systemctl list-dependencies <name>.service or systemctl list-dependencies --all <name>.service to see its dependencies

systemctl show <name>.service to see the low level details

systemctl edit <name>.service or systemctl edit --full <name>.service to edit it without dealing with its path followed by systemctl daemon-reload to have effect

Available units can be seen by

ls /usr/lib/systemd/system

systemctl --all --full

systemctl list-units or simply systemctl

systemctl list-units --all

systemctl list-unit-files

Customization can be made by copying and modifying those files to /etc/systemd/system

systemd calls more or less it units in parallel. If a unit calls an other that is not ready, then systemd buffers the request using sockets.

Systemd can create automatically additional units as when devices are pluged in. Therefore it uses in udev rules


Systemd targets

systemd targets are units as well but are used to group units and have them started together and form therefore something similar as runlevels in a sysvinit system.

systemctl list-unit-files --type=target lists the unit files that are targets

Adding a services to the list of being started at boot (the is more uniform:

systemctl enable <name>.service enable automatic start at boot

systemctl disable <name>.service disable automatic start at boot

systemctl get-default shows the targets that are run at boot

Other targets exist as,

systemctl set-default sets it

Finally everything are links so the same could be achieved by ln -sf /lib/systemd/system/ /etc/systemd/system/ makes the multiuser-target the default target.

systemctl list-dependencies show what depends on it.

systemctl isolate will stop all targets except the

Journal the systemd logger

systemd does not need a logger since it includes the logger journal. It can be configured via /etc/systemd/journald.conf

To have the log stored on the disk /var/log/journal


or mkdir -p /var/log/journal

To set maximum size on disk


Limits to 50MByte if this is missing it will be limited to 10% of the partition size.

The log is binary and not ASCII and can be read via journalctl, for just the current boot journalctl -b or for the kernel messages journalctl -k.

journalctl -u <name>.service will show what has been logged for a service.

The journal can feed a classic logger by systemctl enable syslog-ng so the log becomes ASCII again.

Linurs Servernest startpage