Chapter 19. System initialization

Table of Contents

19.1. The bootloader
19.2. init
19.3. Initialization scripts
19.4. Hotplugging and device node management
19.5. Device firmware

This chapter describes the initialization of Slackware Linux. Along the way various configuration files that are used to manipulate the initialization process are described.

19.1. The bootloader

Arguably the most important piece of an operating system is the kernel. The kernel manages hardware resources and software processes. The kernel is started by some tiny glue between the system BIOS (Basic Input/Output System) and the kernel, called the bootloader. The bootloader handles the complications that come with loading a specific (or less specific) kernel.

Most bootloader actually work in two stages. The first stage loader loads the second stage loader, that does the real work. The boot loader is divided in two stages on x86 machines, because the BIOS only loads one sector (the so-called boot sector) that is 512 bytes in size.

Slackware Linux uses the LILO (LInux LOader) boot loader. This bootloader has been in development since 1992, and is specifically written to load the Linux kernel. Lately LILO has been replaced by the GRUB (GRand Unified Bootloader) in most GNU/Linux distributions. GRUB is available as an extra package on the Slackware Linux distribution media.

19.1.1. LILO configuration

LILO is configured through the /etc/lilo.conf configuration file. Slackware Linux provides an easy tool to configure LILO. This configuration tool can be started with the liloconfig command, and is described in the installation chapter (Section 5.3, “Installing Slackware Linux”).

Manual configuration of LILO is pretty simple. The LILO configuration file usually starts off with some global settings:

# Start LILO global section
boot = /dev/sda 1
#compact        # faster, but won't work on all systems.
prompt 2
timeout = 50 3
# Normal VGA console
vga = normal 4
      

1

The boot option specifies where the LILO bootloader should be installed. If you want to use LILO as the main bootloader for starting Linux and/or other operating systems, it is a good idea to install LILO in the MBR (Master Boot Record) of the hard disk that you use to boot the system. LILO is installed to the MBR by omitting the partition number, for instance /dev/hda or /dev/sda. If you want to install LILO to a specific partition, add a partition number, like /dev/sda1. Make sure that you have another bootloader in the MBR, or that the partition is made active using fdisk. Otherwise you may end up with an unbootable system.

Be cautious if you use partitions with a XFS filesystem! Writing LILO to an XFS partition will overwrite a part of the filesystem. If you use an XFS root (/) filesystem, create a non-XFS /boot filesystem to which you install LILO, or install LILO to the MBR.

2

The prompt option will set LILO to show a boot menu. From this menu you can select which kernel or operating system should be booted. If you do not have this option enabled, you can still access the bootloader menu by holding the <Shift> key when the bootloader is started.

3

The timeout value specifies how long LILO should wait before the default kernel or OS is booted. The time is specified in tenths of a second, so in the example above LILO will wait 5 seconds before it proceeds with the boot.

4

You can specify which video mode the kernel should use with the vga option. When this is set to normal the kernel will use the normal 80x25 text mode.

The global options are followed by sections that add Linux kernels or other operating systems. Most Linux kernel sections look like this:

image = /boot/vmlinuz 1
  root = /dev/sda5 2 
  label = Slack 3
  read-only 4
      

1

The image option specifies the kernel image that should be loaded for this LILO item.

2

The root parameter is passed to the kernel, and will be used by the kernel as the root (/) filesystem.

3

The label text is used as the label for this entry in the LILO boot menu.

4

read-only specifies that the root filesystem should be mounted read-only. The filesystem has to be mounted in read-only state to conduct a filesystem check.

19.1.2. LILO installation

LILO does not read the /etc/lilo.conf file during the second stage. So, you will have to write changes to the second stage loader when you have changed the LILO configuration. This is also necessary if you install a new kernel with the same filename, since the position of the kernel on the disk may have changed. Reinstalling LILO can simply be done with the lilo command:

# lilo
Added Slack26 *
Added Slack
      

19.2. init

After the kernel is loaded and started, the kernel will start the init command. init is the parent of all processes, and takes care of starting the system initialization scripts, and spawning login consoles through agetty. The behavior of init is configured in /etc/inittab.

The /etc/inittab file is documented fairly well. It specifies what scripts the system should run for different runlevels. A runlevel is a state the system is running in. For instance, runlevel 1 is single user mode, and runlevel 3 is multi-user mode. We will have a short look at a line from /etc/inittab to see how it works:

rc:2345:wait:/etc/rc.d/rc.M
    

This line specifies that /etc/rc.d/rc.M should be started when the system switches to runlevel 2, 3, 4 or 5. The only line you probably ever have to touch is the default runlevel:

id:3:initdefault:
    

In this example the default runlevel is set to 3 (multiuser mode). You can set this to another runlevel by replacing 3 with the new default runlevel. Runlevel 4 can particularly be interesting on desktop machines, since Slackware Linux will try to start the GDM, KDM or XDM display manager (in this particular order). These display managers provide a graphical login, and are respectively part of GNOME, KDE and X11.

Another interesting section are the lines that specify what command should handle a console. For instance:

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

This line specifies that agetty should be started on tty1 (the first virtual terminal) in runlevels 1, 2, 3 and 5. The agetty command opens the tty port, and prompts for a login name. agetty will then spawn login to handle the login. As you can see from the entries, Slackware Linux only starts one console in runlevel 6, namely tty6. One might ask what happened to tty0, tty0 certainly exists, and represents the active console.

Since /etc/inittab is the right place to spawn agetty instances to listen for logins, you can also let one or more agetties listen to a serial port. This is especially handy when you have one or more terminals connected to a machine. You can add something like the following line to start an agetty instance that listens on COM1:

s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
    

19.3. Initialization scripts

As explained in the init (Section 19.2, “init”) section, init starts some scripts that handle different runlevels. These scripts perform jobs and change settings that are necessary for a particular runlevel, but they may also start other scripts. Let's look at an example from /etc/rc.d/rc.M, the script that init executes when the system switches to a multi-user runlevel:

# Start the sendmail daemon:
if [ -x /etc/rc.d/rc.sendmail ]; then
  . /etc/rc.d/rc.sendmail start
fi
    

These lines say “execute /etc/rc.d/rc.sendmail start if /etc/rc.d/rc.sendmail is executable”. This indicates the simplicity of the Slackware Linux initialization scripts. Different functionality, for instance network services, can be turned on or off, by twiddling the executable flag on their initialization script. If the initialization script is executable, the service will be started, otherwise it will not. Setting file flags is described in Section 8.5.2, “Changing file permission bits”, but we will have a look at a quick example how you can enable and disable sendmail.

To start sendmail when the system initializes, execute:

# chmod +x /etc/rc.d/rc.sendmail
    

To disable starting of sendmail when the system initializes, execute:

# chmod -x /etc/rc.d/rc.sendmail
    

Most service-specific initialization scripts accept three parameters to change the state of the service: start, restart and stop. These parameters are pretty much self descriptive. For example, if you would like to restart sendmail, you could execute:

# /etc/rc.d/rc.sendmail restart
    

If the script is not executable, you have to tell the shell that you would like to execute the file with sh. For example:

# sh /etc/rc.d/rc.sendmail start
    

19.4. Hotplugging and device node management

Slackware Linux has supported hotplugging since Slackware Linux 9.1. When enabled, the kernel passes notifications about device events to a userspace command. Since Slackware Linux 11.0, the udev set of utilities handle these notifications. udev manages the dynamic /dev directory as well.

The mode of operation of udev for handling hotplugging of devices is fairly simple. When a device is added to the system, the kernel notifies userspace hotplug event listeners. udev will receive the notification of the device being added, and looks whether there are any module mappings for the device. If there are, the appropriate device driver module for the device is automatically loaded. udev will remove the module when it is notified of a device removal, and no devices use the loaded module anymore.

The udev subsystem is initialized in /etc/rc.d/rc.S by executing /etc/rc.d/rc.udev start. As with most functionality, you can enable or disable udev by twiddling the executable flag of the /etc/rc.d/rc.udev script (see Section 19.3, “Initialization scripts”).

If udev automatically loads modules that you do not want to load, you can add a blacklist in your modprobe configuration in /etc/modprobe.d/blacklist. For example, if you would like to prevent loading of the 8139cp module, you can add the following line (actually, this module is already blacklisted in Slackware Linux):

blacklist 8139cp
    

19.5. Device firmware

19.5.1. Introduction

Some hardware requires the system to upload firmware. Firmware is a piece of software that is used to control the hardware. Traditionally, the firmware was stored permanently in ROM (read-only memory) or non-volatile media like flash memory. However, many new devices use volatile memory to store firmware, meaning that the firmware needs to be reloaded to the device memory when the system is restarted.

Drivers for devices that require firmware have a table of the firmware files that it needs. For each firmware file that the driver needs, it will issue a firmware addition event. If udev handles hotplugging events, it will try to handle that event. The udev rules contain an entry for firmware addition events in /etc/udev/rules.d/50-udev.rules:

# firmware loader
SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/firmware.sh"
      

This means that upon firmware addition events, the /lib/udev/firmware.sh script should be executed. This script searches the /lib/firmware and /usr/local/lib/firmware directories for the requested firmware. If the firmware file exists, it will be loaded by copying the contents of the file to a special sysfs node.

19.5.2. Adding firmware

As described in the previous section, some hardware requires firmware to be uploaded to hardware by the operating system. If this is the case, and no firmware is installed, the kernel will emit an error message when the driver for that hardware is loaded. You can see the kernel output with the dmesg command or in the /var/log/messages log file. Such error message explicitly says that the firmware could not be loaded, for example:

ipw2100: eth1: Firmware 'ipw2100-1.3.fw' not available or load failed.
ipw2100: eth1: ipw2100_get_firmware failed: -2 
      

In this case you will have to find the firmware for your device. This can usually be found by searching the web for the chipset or driver for the device (in this case ipw2100) and the literal term “firmware”. The firmware archive often contains a file with installation instructions. Usually you can just copy the firmware files to /lib/firmware.

After installing the firmware, you can reload the driver with rmmod and modprobe, or by restarting the system.