Boot process of linux in detail
LINUX BOOT PROCESS
When an x86 computer is booted, the processor looks at the end of the system memory for the BIOS (Basic Input/Output System) and runs it. The BIOS program is written into permanent read-only memory and is always available for use. The BIOS provides the lowest level interface to peripheral devices and controls the first step of the boot process.
The BIOS tests the system, looks for and checks peripherals, and then looks for a drive to use to boot the system. Usually it checks the floppy drive (or CD-ROM drive on many newer systems) for bootable media, if present, and then it looks to the hard drive. The order of the drives used for booting is usually controlled by a particular BIOS setting on the system. Once Linux is installed on the hard drive of a system, the BIOS looks for a Master Boot Record (MBR) starting at the first sector on the first hard drive, loads its contents into memory, then passes control to it.
This MBR contains instructions on how to load the GRUB (or LILO) boot-loader, using a pre-selected operating system. The MBR then loads the boot-loader, which takes over the process (if the boot-loader is installed in the MBR). In the default Red Hat Linux configuration, GRUB uses the settings in the MBR to display boot options in a menu. Once GRUB has received the correct instructions for the operating system to start, either from its command line or configuration file, it finds the necessary boot file and hands off control of the machine to that operating system.
GRUB features
This boot method is called direct loading because instructions are used to directly load the operating system, with no intermediary code between the boot-loaders and the operating system’s main files (such as the kernel). The boot process used by other operating systems may differ slightly from the above, however. For example, Microsoft’s DOS and Windows operating systems completely overwrite anything on the MBR when they are installed without incorporating any of the current MBR’s configuration. This destroys any other information stored in the MBR by other operating systems, such as Linux. The Microsoft operating systems, as well as various other proprietary operating systems, are loaded using a chain loading boot method. With this method, the MBR points to the first sector of the partition holding the operating system, where it finds the special files necessary to actually boot that operating system.
GRUB supports both boot methods, allowing you to use it with almost any operating system, most popular file systems, and almost any hard disk your BIOS can recognize.
GRUB contains a number of other features; the most important include:
1)GRUB provides a true command-based, pre-OS environment on x86 machines to allow maximum flexibility in loading operating systems with certain options or gathering information about the system.
2)GRUB supports Logical Block Addressing (LBA) mode, needed to access many IDE and all SCSI hard disks. Before LBA, hard drives could encounter a 1024-cylinder limit, where the BIOS could not find a file after that point.
3)GRUB’s configuration file is read from the disk every time the system boots, preventing you from having to write over the MBR every time you change the boot options.
=================================================================================
Lilo
1. In case of a multi-boot config, LiLo permits the user two choose an operating system from the menu. The LiLo settings are stored at /etc/lilo.conf. System administrators use this file for a very detailed finement of the loader. Here can be manually set what operating systems are installed, as well as the method for loading any of them. If on the computer there is only Linux, LiLo can be set to load directly the kernel, and skip the selection menu.
2. The Linux kernel is compressed, and contains a small bit, which will decompress it. Immediately after the first step begins the decompression and the loading of the kernel.
3. If the kernel detects that your graphics card supports more complex text modes, Linux allows the usage of them – this can be specified or during the recompilation of the kernel, or right inside Lilo, or other program, like rdev.
4. The kernel verifies hardware configuration (floppy drive, hard disk, network adapters, etc) and configures the drivers for the system. During this operation, several informative messages are shown to the user.
5. The kernel tries to mount the file system and the system files. The location of system files is configurable during recompilation, or with other programs – LiLo and rdev. The file system type is automatically detected. The most used file systems on Linux are ext2 and ext3. If the mount fails, a so-called kernel panic will occur, and the system will “freeze”.
System files are usually mounted in read-only mode, to permit a verification of them during the mount. This verification isn’t indicated if the files were mounted in read-write mode.
6. After these steps, the kernel will start init, which will become process number 1, and will start the rest of the system.
=================================================================================
The great thing about GRUB is that it includes knowledge of Linux file systems. Instead of using raw sectors on the disk, as LILO does, GRUB can load a Linux kernel from an ext2 or ext3 file system. It does this by making the two-stage boot loader into a three-stage boot loader. Stage 1 (MBR) boots a stage 1.5 boot loader that understands the particular file system containing the Linux kernel image.
With the second-stage boot loader in memory, the file system is consulted, and the default kernel image and initrd image are loaded into memory. With the images ready, the stage 2 boot loader invokes the kernel image.The routine then calls the kernel and the kernel boot begins.
During the boot of the kernel, the initial-RAM disk (initrd) that was loaded into memory by the stage 2 boot loader is copied into RAM and mounted. This initrd serves as a temporary root file system in RAM and allows the kernel to fully boot without having to mount any physical disks. Since the necessary modules needed to interface with peripherals can be part of the initrd, the kernel can be very small, but still support a large number of possible hardware configurations. After the kernel is booted, the root file system is pivoted (via pivot_root) where the initrd root file system is unmounted and the real root file system is mounted.
With the kernel image in memory and control given from the stage 2 boot loader, the kernel stage begins. The kernel image isn’t so much an executable kernel, but a compressed kernel image. Typically this is a zImage (compressed image, less than 512KB) or a bzImage (big compressed image, greater than 512KB), that has been previously compressed with zlib. At the head of this kernel image is a routine that does some minimal amount of hardware setup and then decompresses the kernel contained within the kernel image and places it into high memory.
After the kernel is booted and initialized, the kernel starts the first user-space application.
The init process
It’s Linux’s first process, and parent of all the other processes. This process is the first running process on any Linux/UNIX system, and is started directly by the kernel. It is what loads the rest of the system, and always has a PID of 1.
The initialization files in /etc/inittab
First time the initialization process (init) examines the file /etc/inittab to determine what processes have to be launched after. This file provides init information on runlevels, and on what process should be launched on each runlevel.
After that, init looks up the first line with a sysinit (system initialization) action and executes the specified command file, in this case /etc/rc.d/rc.sysinit. After the execution of the scripts in /etc/rc.d/rc.sysinit, init starts to launch the processes associated with the initial runlevel.
The next few lines in /etc/inittab are specific to the different execution (run-) levels. Every line runs as a single script (/etc/rc.d/rc), which has a number from 1 to 6 as argument to specify the runlevel.
The most used action in /etc/inittab is wait, which means init executes the command file for a specified runlevel, and then waits until that level is terminated.
The files in /etc/rc.d/rc.sysinit
The commands defined in /etc/inittab are executed only once, by the init process, every time when the operating system boots. Usually these scripts are running as a succession of commands, and usually realise the following:
1. Determine whether the system takes part of a network, depending on the content of /etc/sysconfig/network
2. Mount /proc, the file system used in Linux to determine the state of the diverse processes.
3. Set the system time in fuction to the BIOS settings, as well as realises other settings (setting of time zone, etc), stabilized and configured during the installation of the system.
4. Enables virtual memory, activating and mounting the swap partition, specified in /etc/fstab (File System Table)
5. Sets the host name for the network and system wide authentication, like NIS (Network Information Service), NIS+ (an improved version of NIS), and so on.
6. Verifies the root fily system, and if no problems, mounts it.
7. Verifies the other file systems specified in /etc/fstab.
8. Identifies, if case of, special routines used by the operating system to recognize installed hardware to configure Plug’n'Play devices, and to activate other prime devices, like the sound card, for example.
9. Verifies the state of special disk devices, like RAID (Redundant Array of Inexpensive Disks)
10. Mounts all the specified file systems in /etc/fstab.
11. Executes other system-specific tasks.
The /etc/rc.d/init.d directory
The directory /etc/rc.d/init.d contains all the commands which start or stop services which are associated with all the execution levels.
All the files in /etc/rc.d/init.d have a short name which describes the services to which they’re associated. For example, /etc/rc.d/init.d/amd starts and stops the auto mount daemon, which mounts the NFS host and devices anytime when needed.
The login process
After the init process executes all the commands, files and scripts, the last few processes are the /sbin/mingetty ones, which shows the banner and log-in message of the distribution you have installed. The system is loaded and prepared so the user could log in.
Linux’s execution levels
The execution levels represent the mode in which the computer operates. They are defined by a set of available services at any time they are started. The execution levels represent different ways Linux uses to be available to you, the user, or eventually the administrator.
As daily user you don’t have to bother with the execution levels, although the multi-user level makes the services which you need while using Linux in a network (though in a transparent mode) available.
In the next few sentences I’ll present the execution levels, one by one:
0: Halt (stops all running processes and executes shutdown)
1: Known under the name “Single-user mode”. In this case the system runs with a reduced set of services and daemons. The root file system is mounted read-only. This runlevel is used when the others fail while booting.
2: On this level run the most of the services, with the exception of network services (httpd, named, nfs, etc). This execution level is ideal for the debug of network services, keeping the file system shared.
3: Complete multi-user mode, with network support enabled.
4: Unused, in most of the distributions. In Slackware this level is equivalent with 3, the only difference is that this has graphic login enabled.
5: Complete multi-user mode, with network and graphic subsystem support enabled.
6: Reboot. Stops all running processes and reboots the system to the initial execution level.
Modification of execution levels
The most used facility of init, and maybe the most confusing one, is the ability to move from an execution level to an other.
The system boots into a runlevel specified in /etc/inittab, or to a level specified at the LiLo prompt. To change the execution level, use the command init. For example, to change the execution level to 3, type
init 3
This stops most of the processes and takes the system into a multi-user mode with networking enabled. Attention, changing the init level might force several daemons used at the moment to stop!
The directories of execution levels
Every execution level has a directory with a symbolic links (symlinks) pointing to the corresponding scripts in /etc/rc.d/init.d. These directories are:
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc/rc.d/rc6.d
The name of the symlinks are semnificative. It specifies which service has to be stopped, started and when. The links starting with an “S” are programmed to start in various execution levels. The links also have a number in their name (01-99). Now some examples of symlinks in the directory /etc/rc.d/rc2.d:
K20nfs -> ../init.d/nfs
K50inet -> ../init.d/inet
S60lpd -> ../init.d/lpd
S80sendmail -> ../init.d/sendmail
When operating systems change the execution level, init compares the list of the terminated processes (links which start with “K”) from the directory of the current execution level with the list of processes which have to be started (starting with “S”), found in the destination directory.
I got this from one journal and it looks informative
==========================================================
The first step of the BIOS is the power-on self test (POST). The job of the POST is to perform a check of the hardware. The second step of the BIOS is local device enumeration and initialization.
To boot an operating system, the BIOS runtime searches for devices that are both active and bootable in the order of preference defined by the complementary metal oxide semiconductor (CMOS) settings. A boot device can be a floppy disk, a CD-ROM, a partition on a hard disk, a device on the network, or even a USB flash memory stick.
Commonly, Linux is booted from a hard disk, where the Master Boot Record (MBR) contains the primary boot loader. The MBR is a 512-byte sector, located in the first sector on the disk (sector 1 of cylinder 0, head 0). After the MBR is loaded into RAM, the BIOS yields control to it.
The job of the primary boot loader is to find and load the secondary boot loader (stage 2). It does this by looking through the partition table for an active partition. When it finds an active partition, it scans the remaining partitions in the table to ensure that they’re all inactive. When this is verified, the active partition’s boot record is read from the device into RAM and executed.
The great thing about GRUB is that it includes knowledge of Linux file systems. Instead of using raw sectors on the disk, as LILO does, GRUB can load a Linux kernel from an ext2 or ext3 file system. It does this by making the two-stage boot loader into a three-stage boot loader. Stage 1 (MBR) boots a stage 1.5 boot loader that understands the particular file system containing the Linux kernel image.
With the second-stage boot loader in memory, the file system is consulted, and the default kernel image and initrd image are loaded into memory. With the images ready, the stage 2 boot loader invokes the kernel image.The routine then calls the kernel and the kernel boot begins.
During the boot of the kernel, the initial-RAM disk (initrd) that was loaded into memory by the stage 2 boot loader is copied into RAM and mounted. This initrd serves as a temporary root file system in RAM and allows the kernel to fully boot without having to mount any physical disks. Since the necessary modules needed to interface with peripherals can be part of the initrd, the kernel can be very small, but still support a large number of possible hardware configurations. After the kernel is booted, the root file system is pivoted (via pivot_root) where the initrd root file system is unmounted and the real root file system is mounted.
With the kernel image in memory and control given from the stage 2 boot loader, the kernel stage begins. The kernel image isn’t so much an executable kernel, but a compressed kernel image. Typically this is a zImage (compressed image, less than 512KB) or a bzImage (big compressed image, greater than 512KB), that has been previously compressed with zlib. At the head of this kernel image is a routine that does some minimal amount of hardware setup and then decompresses the kernel contained within the kernel image and places it into high memory.
After the kernel is booted and initialized, the kernel starts the first user-space application.
In a desktop Linux system, the first application started is commonly /sbin/init
The program /sbin/init is started by the “idle” process (Process 0) code in linux/init/main.c and becomes process 1. /sbin/init then completes the initialization by running scripts and forking additional processes as specified in /etc/inittab. It starts by printing:
INIT: version 2.76 booting
and reads /etc/inittab, a copy of which follows:
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.8 1998/05/10 10:37:50 miquels Exp $
# The default runlevel.
id:2:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
b::boot:echo “INIT: boot action…”
bw::bootwait:echo “INIT: boot wait action – sleeping 5 seconds…”; sleep(5); echo “done napping…”
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d/rc executes the Snn and Knn scripts in order upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# The following run when you do ‘telinit A’ or ‘telinit B’ and are disconnected from
# getting Ctrl-C, Ctrl-\, and Ctrl-Z from the keyboard. Ctrl-D will logout from the
# current version of bash that has been temporarily replaced by the “demand” program.
# The demand program’s parent is init, not bash, and bash can still be used even
# though the output from the demand program is going to the same terminal.
#
la:A:wait:/home/c/sigplayposix
lb:B:wait:/home/c/sigplayold
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
# shutdown -t1 => 1 second pause before shutdown
# shutdown -a => use /etc/shutdown.allow (root always allowed)
# shutdown -r => reboot after shutdown
# shutdown -h => halt after shutdown
# What to do when the power fails/returns.
pf::powerwait:/etc/init.d/powerfail start
pn::powerfailnow:/etc/init.d/powerfail now
po::powerokwait:/etc/init.d/powerfail stop
# /sbin/getty invocations for the runlevels.
#
# The “id” field MUST be the same as the last
# characters of the device (after “tty”).
#
# Format:
# :::
1:12345:respawn:/sbin/agetty 9600 tty1
2:2345:respawn:/sbin/agetty 9600 tty2
3:2345:respawn:/sbin/agetty 9600 tty3
4:2345:respawn:/sbin/agetty 9600 tty4
5:2345:respawn:/sbin/agetty 9600 tty5
6:2345:respawn:/sbin/agetty 9600 tty6
x:5:respawn:/usr/X11R6/bin/xdm -nodaemon
#n1:234:wait:/etc/init.d/rc.inet1
#n2:234:wait:/etc/init.d/rc.inet2
# Example how to put a getty on a serial line (for a terminal)
#
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
#T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100
# Example how to put a getty on a modem line.
#
#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3
When this is processed at the very end of the booting process, the following lines are printed:
Activating swap…
Checking root filesystem…
Parallelizing fsck version 1.04 (16-May-96)
Checking all file systems.
[/sbin/fsck.ext2]fsck.ext2 -a /dev/sdb5
/dev/sdb5: clean, 26562/261120 files, 545241/1044193 blocks
Checking all filesystems…
Parallelizing fsck version 1.04 (16-May-96)
/dev/sda2: clean, 28715/376832 files, 1174190/1502077 blocks
/dev/sda7: clean, 450/26104 files, 15544/104391 blocks
Mounting local file systems…
/proc on /proc type proc (rw)
/dev/sda2 on /mnt/extra type ext2 (rw)
/dev/sdia7 on /mnt/backup type ext2 (rw)
Telling the kernel that the machine time is local, not GMT
Mon Nov 29 19:47:59 PST 1999
Cleaning up: /tmp /var/lock /var/run.
Starting System logger: syslogd.
Starting Kernel logger: klogd.
Starting BSD Printer daemon lpd: lpd.
Initializing random number generator… done.
INIT: Bootwait action – sleeping 5 seconds…
INIT: Boot (no wait) – sleeping 15 seconds…
INIT: Bootwait – Done napping.
Upon entering run level 2 it prints:
INIT: Entering runlevel: 2
Notice how /sbin/init waited for the bootwait action to finish before going to run level 2, the default runlevel specified by the id:2:default: entry in /etc/inittab. At this point all actions which are associated with runlevel 2 are started. Specifically, for this simplified /etc/inittab these are:
rc 2
/etc/init.d/rc takes the parameter 2 and walks through each link in the directory /etc/rc2.d, killing (“K”) or starting (“S”) scripts in the order specified by their numbering (“00″ through “99″). An alternate arrangement for these script files has them placed one directory lower in (/etc/rc.d/rc2.d, etc.).
/etc/inittab also specifies that all 6 virtual consoles shall be set up in run level 2:
/sbin/agetty 9600 tty1
/sbin/agetty 9600 tty2
/sbin/agetty 9600 tty3
/sbin/agetty 9600 tty4
/sbin/agetty 9600 tty5
/sbin/agetty 9600 tty6
Each of the agetty’s starts a login shell, /sbin/login, and after a log-in, starts /bin/sh which is typically a symbolic link to /bin/bash.
At this point most distributions clear the screen and set the cursor set to the top left character.
For illustrative purposes, I have made my /etc/init.d/rcS script indicate when it is started and we get the following:
Starting initscript…
Starting initscript…
Starting initscript…
Starting initscript…
Starting initscript…
Starting initscript…
Starting initscript…
/sbin/login copies the file /etc/issue to the screen before prompting for the user name and password:
Kanji-Flash Softworks
Baldy login: INIT: Boot (no wait) – Done napping.root
Password:
Last login: Mon Nov 29 17:54:57 1999 on tty2
Linux Baldy 2.2.12 #1 Thu Nov 4 19:44:40 PST 1999 i686 unknown
# The Bash Shell is Started
The bash shell, /bin/bash is then started up. Bash initialization begins by executing script in /etc/profile which set the system-wide environment variables:
# /etc/profile
# System wide environment and startup programs
# Functions and aliases go in $HOME/.bashrc
export PATH=”/bin:/usr/bin:/usr/X11R6/bin:/opt/bin:/usr/local/bin:/usr/local/java/bin:./”
umask 022
if [ `id -gn` = `id -un` ] && [ `id -u` != 0 ]; then
umask 002
fi
if [ -z "$UID" ]; then
UID=`id -u`
fi
if [ "$UID" = 0 ]; then
PATH=/sbin:/usr/sbin:$PATH
else
PATH=$PATH:
fi
export USER=`id -un`
export LOGNAME=$USER
export HOSTNAME=`/bin/hostname`
export LOCATE_PATH=/var/state/misc/locatedb
Next, Bash executes the script in /root/.profile for user-specific customizations:
# ~/.profile –
# The personal initialization file, executed for login shells
if [ -n "$BASH_VERSION" ]; then
if [ -r "$HOME/.bashrc" ]; then
# login shells are always interactive, are they?
. $HOME/.bashrc
fi
fi
In this case, it merely has the shell execute the script .bashrc in the user’s home directory. Both .profile and .bashrc set user-specific customizations, but only .bashrc is run at each shell invocation. .profile is only run at log-in.
In my case for root, /root/.bashrc contains:
#Make backspace work as expected by PC users but otherwise leave as expected by remote terminal users.
if [ -z "$TERM" ]; then
echo “.bashrc: TERM empty: this shouldn’t happen!” 1>&2
echo ” Please contact ‘support@lst.de’” 1>&2
else
case $TERM in
linux*)
stty erase ‘^?’
;;
*)
stty erase ‘^H’
;;
esac
fi
#Exports some environmental variables:
#export GROFF_TYPESETTER=latin1
#export LC_CTYPE=iso-8859-1
#export METAMAIL_PAGER=less
export LESSCHARSET=latin1
export PS1=”\[\033[0m\033[1;32m\][\d - \@: \w]\\$\[\033[1;37m\] ”
export TERMINFO=/usr/lib/terminfo
export HISTSIZE=200
export LD_LIBRARY_PATH=/usr/local/lib
export PRINTER=magic
export LS_COLORS=’no=01;37:fi=01:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:’
#Set some aliases:
alias which=’type -path’
alias ll=”ls –almost-all -l –classify –full-time –color”
alias ls=”ls -A –color”
alias showhex=”/usr/bin/hexdump -f /etc/hexdump.fmt”
alias cc=”gcc -DEOF=-1 -Wall -lintl”
alias whatfor=”whatfor –color –all”
alias last=”last -n 10 -a -x”
alias less=”less –raw-control-chars –LONG-PROMPT –force”
alias pssig=”ps -sx –forest”
alias psx=”ps -o user,ppid,pid,pgid,tty,stat,command –forest x”
alias psw=”ps -aux –forest”
#Set some key bindings for bash’s command line input:
# Home
bind ‘”\e[1~": beginning-of-line'
# Insert
bind '"\e[2~": abort'
# Delete
bind '"\e[3~": delete-char'
# End
bind '"\e[4~": end-of-line'
# Page Up
bind '"\e[5~": abort'
# Page Down
bind '"\e[6~": abort'
#Sets tab stops to every 4th character:
setterm -clrtabs
setterm -regtabs 4
Finally, bash initialization is complete and we get the bash prompt.
[redhatserver249: ~]#
Category: Linux Administration
