Subject: Booting Debian [draft]

From: [email-masked] (Bernd Eckenfels)
Date: Sun, 7 Jul 1996 00:51:15 +0200 (MET DST)

Hi,

here is a small text, describing how debian boots the system, after the
Kernel is loaded. This is a first draft, comments welcome. The file is for
information of the users, and intended as a base-document for changes in the
boot sequence.

----------------------------------------------------------------
Booting Debian Linux 1.1

This file describes how a Debian Linux system will boot after the Kernel is
loaded by the boot-loader like lilo, loadlin or syslinux.

1. Directories
--------------

/     Root. Usually there are symlinks (vmlinuz, vmlinuz.old, System.map and
      System.old) pointing to the current and last kernel in /boot/

/lib/modules/ If there are any modules they are stored under this dir. For
              every kernelversion there is a subdir (named `uname -r`) with
              the sections block/, fs/, ipv4/, misc/ and net/. A file for
              dependecies (modules.dep) is located there, too. The symlink
              /etc/modules/current@ should point to the current (running) 
              kernel version.

/lib/modules/boot/ contains modules (usually symlinks to 
                   /lib/modules/current/../.. which should be loaded
                   statically after boot. They can be specified in
                   /etc/modules, too.

/boot/ Here are the current kernelimages (vmlinuz-x.x.x) and Symbol Tables
       (System.map-x.x.x) stored. Additionally bootloader can store their
       images, too. Generally the data in this directory has to be accesable
       by the system's BIOS.

/etc/ Directory for configuration files.

/etc/init.d/ Directory for bootscripts. All scripts used to bring the system
             up (in multi-user mode) should be located here and referenced
             with symlinks.

/etc/rc.boot/ Scripts to initialize the system after reboot, before entering
              any runlevel.

/etc/rcX.d/ Scripts to start/stop subsystems if entering/leaving a runlevel.

2. Runlevels
-------------

S       - internally used for single user mode
0       - halt the system
1       - get system down to single user mode
2-5,7-9 - diferent modes of operation
          2   - stand alone mode, no accounting
	  3-5 - normal operation
          7-9 - unused.
6       - reboot system

3. The Boot Sequence
--------------------

3.1 init
--------

As the last step of booting, the kernel starts init(8) with a PID of 1. Init
cecks the command-line arguments and reads /etc/inittab. Unless you have
specified "-b" or "emergency" at the kernel command line, init(8) starts the
script /etc/init.d/boot as specified with "sysinit" in the inittab(5) as
discussed in 3.1.1.

After /etc/init.d/boot is finished init tries to guess the runlevel to
switch to. If a runlevel was given at the kernel command line, it will
switch to this runlevel, otherwise it will switch to the default runlevel in
inittab(5) in the line "initdefault" (usually runlevel 2 or 3). If there is
no default-runlevel init asks for the runlevel at the console.

Everytime the runlevel is changed init executes the script /etc/init.d/rc
with the first argument holding the new runlevel. This script is used to run
the start/stop scripts as discussed in 3.1.2. After that init executes
programs like getty mentioned in the inittab(5). 

Rebooting, halting or going to single user mode is just a simple switch to
runlevel 6, 0 or 1. The last step of runlevel 1 is to switch to runlevel s,
which will start the program specified in the ~~:S:wait:/sbin/sulogin line.
The last step of runlevel 6 or 0 is to start /etc/init.d/reboot or halt as
described in 3.1.3.

3.1.1 /etc/init.d/boot
----------------------

The script first checks if /sbin/unconfigured.sh exists and executes it
(used for installing a debian system). After that it execute sulogin(8)
if $SULOGIN is set at the beginning of the script. This emulates SCO's 
behaviour of presenting a single-user shell before any runlevel is entered.

The next step is to activate the md driver for multiple devices, if a
/etc/mdtab file is present (mdtab(5) is describing which physical devices
should be pluged together to a single logical one).

Then the swap (as configured in fstab(5)) is turned on, cause fsck needs a
lot of memory on big partitions.

The update(8) daemon is started (bdflush).

If the file /fastboot is present the next step is skiped.

To ensure the root is mounted read-only it is remounted. If this succeeds
fsck(8) is called for all filesystems mentioned in the fstab. (fsck returns
an error code > 1, if there was a serious problem, which will force the
script to give a large warning message and to start sulogin. If sulogin is
exited, the system will be reboot(8)ed after a sync(8).)

The next step is to remount the root filesystem read-write without writing
/etc/mtab. Then the flagfile /etc/nologin and /fastboot are deleted, the
mounttable /etc/mtab and the lockfile /etc/mtab~ is removed. With an
additional faked mount(8) the first entry for the root filesystem will be
written in /etc/mtab.

The /etc/init.d/boot script checks if the module packages has installed a
script /etc/init.d/modules, used to configure the modules subsystem of the
linux kernel as described in 3.1.1.1.

After the modules are loaded (and possibly the kerneld started) all of the
filesystems mentioned in /etc/fstab are mounted (except for those marked
with noauto or those with type=nfs).

After that the swap is activated again, just in case there are any
additional swapfile accessable after the mount.

/etc/init.d/network is called to start the network interfaces (like lo or
eth0) as specified on system installation.

After that the hostname is set from /etc/hostname with the hostname(1)
command. 

The next step performed will mount all of the nfs-filesystems mentioned in
/etc/fstab.

Then the system clock is set from the CMOS clock with clock(1) and if not
present a file for adjusting the clock /etc/adjtime is generated and
updated.

The local time is printed.

After that the /tmp directory is cleaned, stale locks in /var/lock and
stale PID files in /var/run are rmoved. An empty /var/run/utmp will be
generated.

After that the executable files in /etc/rc.boot/ are executed with
run-parts(8) (see discussion in 3.1.1.2.). 

After that the permissions of all ptys is set to "666 root.tty".

The first line in /etc/motd(5) (which is displayed from login(1) ofter you 
have logged on) will be replaced with the output of uname(1).

The last step in that file is to execute /sbin/setup.sh if present, which is
used for system installation only.

3.1.1.1 /etc/init.d/modules
-------------------------
If there are no modules for the current kernel (/lib/modules/x.x.x/ has to
exist), the script exits immediatelly.

Otherwise the script will point /lib/modules/current/ to the recent version,
and check if there is a modules.dep file. This file lists the dependencies
between the modules and will be generated with depmod(8) if not present. You
can force a dependency generation in this file, if you want to be sure, that
changes in the modules are always mirrored in the dependencies file.

The script now reads /etc/modules line by line and inserts the modules which
are listed there with modprobe(8). If there is a line with "auto" in it
"/etc/init.d/kerneld start" will be called, which simply starts the kerneld.
This is used if you need special modules before any other operation (like
mounting filesystems) is done. 

For compatibility modprobe is used to load all modules from path[boot]
(/lib/modules/boot/) of conf.modules permanent.

3.1.2 /etc/init.d/rc
--------------------

Everytime the runlevel is changed (on boot, halt, reboot or with telinit to
change the mode of operation) /etc/init.d/rc is called from init with a
single argument naming the new desired runlevel.

The SysVinit style of managing runlevels is to maintain a directory for
every runlevel. Those directories are called /etc/rc<runlevel>.d/ and
contain links to start/stop scripts. Those scripts are stored in
/etc/init.d/ and will be executed with an arguemnt start or stop depending
on the situation.

The links in those directories are calles Xyyname with:

 X		S=start this daemon, K=kill this daemon
  yy		two digits number for ordering
    name	descriptive name

yy is a 2 digits number to ensure the scripts are called in the right order.
Every Package can place a script in those directories. If order is
unimportant aa=20 should be used. The script update-rc.(8) is used to
maintain those links.

/etc/init.d/rc will now look at each kill script in the new runlevel. For
each K script it checks if the start and kill scripts in the previos
runlevel are identical. If yes, the killscript is skiped, otherwise it is
executed with the stop option.

After that all S scripts are executed with the start option if they are not
present in the previous runlevel.

Those start/stop scripts are usually used to start and stop daemons or to
set up a special operation mode. start-stop-daemon(8) is used for this.

3.1.3 /etc/init.d/reboot,halt
-----------------------------

To halt or reboot the system /etc/init.d/rc will first execute all the K
scripts in rc0.d or rc1.d. After that the only S script S20halt or S20reboot
is started to reboot or halt the system.

The scripts will first deliver TERM and KILL signals to all running
processes with the kilall5(8) utility to ensure all processes are stoped
(cleanly). After that a reboot record is written to the wtmp with halt(8),
the swap is turned off (with swapoff(8)) and all filesystems are unmounted.
The rootfilesystem will be mounted readonly, to ensure it is clean after
reboot and the system will be halted or rebooted with halt(8).