bootloader
(Written by Paul Cobbaut, https://github.com/paulcobbaut/, with contributions by: Alex M. Schapelle, https://github.com/zero-pytagoras/)
This chapter briefly discusses the boot sequence of an (Intel 32-bit or 64-bit) Linux computer.
Systems booting with lilo
are rare nowadays, so this section is brief.
The most common bootloader on Linux systems today is
grub
, yet this is not a Linux project. Distributions
like FreeBSD
and Solaris
also use grub
.
Likewise, grub
is not limited to Intel architecture. It can also load
kernels on PowerPC.
Note that grub
, while still the default in Debian, is slowly being
replaced in most distributions with grub2
.
boot terminology
The exact order of things that happen when starting a computer system,
depends on the hardware architecture (Intel x86
is
different from Sun Sparc
etc), on the boot loader
(grub
is different from lilo
) and on the operating system (Linux
,
Solaris
, BSD
etc). Most of this chapter
is focused on booting Linux
on Intel x86
with grub
.
post
A computer starts booting the moment you turn on the power (no kidding).
This first process is called post
or
power on self test
. If all goes well then this leads to
the bios
. If all goes not so well, then you might hear nothing, or
hear beeping, or see an error message on the screen, or maybe see smoke
coming out of the computer (burning hardware smells bad!).
bios
All Intel x86
computers will have a basic input/output system
or
bios
to detect, identify and initialize hardware. The
bios
then goes looking for a boot device
. This can be a floppy, hard
disk, cdrom, network card or usb drive.
During the bios
you can see a message on the screen telling you which
key (often Del
or F2
) to press to enter the bios
setup.
openboot
Sun sparc
systems start with openboot
to
test the hardware and to boot the operating system.
Bill Callkins
explains openboot
in his Solaris System
Administration books. The details of openboot
are not the focus of
this course.
boot password
The bios
allows you to set a password. Do not forget this password, or
you will have to open up the hardware to reset it. You can sometimes set
a password to boot the system, and another password to protect the
bios
from being modified.
boot device
The bios
will look for a boot device
in the order configured in the
bios setup. Usually an operating system on a production server boots of
a hard disk.
master boot record
The master boot record
or mbr
is the
first sector of a hard disk. The partitioning of a disk in
primary
partitions, and the active partition are defined
in the mbr
.
The mbr
is 512 bytes long and can be copied with dd
.
dd if=/dev/sda of=bootsect.mbr count=1 bs=512
bootloader
The mbr
is executed by the bios
and contains either (a small)
bootloader
or code to load a bootloader
.
Looking at the mbr
with od
can reveal information
about the bootloader
.
student@linux:~$ sudo dd if=/dev/sda count=1 bs=16 skip=24 2>/dev/null|od -c
0000000 376 G R U B \0 G e o m \0 H a r d
0000020
There are a variety of bootloaders available, most common on Intel
architecture is grub
, which is replacing
lilo
in many places. When installing Linux
on sparc
architecture, you can choose silo
, Itanium
systems can
use elilo
, IBM S/390
and zSeries
use
z/IPL
, Alpha
uses milo
and PowerPC
architectures
use yaboot
(yet another boot loader).
Bootable cd\'s and dvd\'s often use syslinux
.
kernel
The goal of all this is to load an operating system, or rather the
kernel
of an operating system. A typical bootloader like grub
will
copy a kernel from hard disk to memory, and will then hand control of
the computer to the kernel (execute the kernel).
Once the Linux kernel is loaded, the bootloader turns control over to
it. From that moment on, the kernel is in control of the system. After
discussing bootloaders, we continue with the init system
that starts
all the daemons.
grub
/boot/grub/grub.cfg
Debian switched to grub2
, which will be discussed in the
next section. The main boot menu configuration file for grub2
is
grub.cfg
.
root@linux:~# ls -l /boot/grub/grub.cfg
-r--r--r-- 1 root root 2453 May 13 17:22 /boot/grub/grub.cfg
root@linux:~#
/boot/grub/grub.conf
Distributions like Red Hat Enterprise Linux 6 use
grub.conf
and provide a symbolic link from
/boot/grub/menu.lst
and from
/etc/grub.conf
to this file.
[root@linux ~]# ls -l /boot/grub/menu.lst
lrwxrwxrwx. 1 root root 11 Mar 7 11:53 /boot/grub/menu.lst -> ./grub.conf
[root@linux ~]# ls -l /boot/grub/grub.conf
-rw-------. 1 root root 1189 May 5 11:47 /boot/grub/grub.conf
[root@linux ~]#
The file currently (RHEL 6.5) looks like this:
[root@linux ~]# more /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.11.2.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.11.2.el6.x86_64 ro root=/dev/mapper/VolGr\
oup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap \
SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBO\
ARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.11.2.el6.x86_64.img
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-l\
v_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFO\
NT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTY\
PE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
[root@linux ~]#
menu commands
The menu commands
must be at the top of grub
\'s configuration file.
default
The default
command sets a default entry
to start. The
first entry
has number 0.
default=0
Each entry or stanza
starts with a title
directive.
fallback
In case the default
does not boot, use the fallback
entry instead.
fallback=1
timeout
The timeout
will wait a number of seconds before booting
the default
entry.
timeout=5
hiddenmenu
The hiddenmenu
will hide the grub
menu unless the user
presses Esc
before the timeout
expires.
hiddenmenu
title
With title
we can start a new entry
or stanza
.
title CentOS (2.6.32-431.11.2.el6.x86_64)
password
You can add a password
to prevent interactive selection
of a boot environment while grub
is running.
password --md5 $1$Ec.id/$T2C2ahI/EG3WRRsmmu/HN/
Use the grub
interactive shell to create the password hash.
grub> md5crypt
Password: ********
Encrypted: $1$Ec.id/$T2C2ahI/EG3WRRsmmu/HN/
stanza commands
Every operating system
or kernel
that you want to boot with grub
will have a stanza
aka an entry
of a couple of lines.
Listed here are some of the common stanza
commands.
boot
Technically the boot
command is only mandatory when
running the grub command line
. This command does not have any
parameters and can only be set as the last command of a stanza.
boot
kernel
The kernel
command points to the location of the kernel.
To boot Linux this means booting a gzip
compressed
zImage
or bzip2
compressed
bzImage
.
This screenshot shows a kernel
command used to load a Debian kernel.
kernel /boot/vmlinuz-2.6.17-2-686 root=/dev/hda1 ro
And this is how RHEL 5 uses the kernel
command.
kernel /vmlinuz-2.6.18-128.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
All parameters in the kernel line can be read by the kernel itself or by
any other program (which are started later) by reading
/proc/cmdline
initrd
Many Linux
installations will need an initial ramdisk
at boot time.
This can be set in grub
with the initrd
command.
Here a screenshot of Debian 4.0
initrd /boot/initrd.img-2.6.17-2-686
And the same for Red Hat Enterprise Linux 5
initrd /initrd-2.6.18-128.el5.img
root
The root
command accepts the root device as a parameter.
The root
command will point to the hard disk and partition to use,
with hd0
as the first hard disk device and hd1
as the second hard
disk device. The same numbering is used for partitions, so hd0,0
is
the first partition on the first disk and hd0,1
is the second
partition on that disk.
root (hd0,0)
savedefault
The savedefault
command can be used together with
default saved
as a menu command. This combination will
set the currently booted stanza as the next default stanza to boot.
default saved
timeout 10
title Linux
root (hd0,0)
kernel /boot/vmlinuz
savedefault
title DOS
root (hd0,1)
makeactive
chainloader +1
savedefault
chainloading
With grub
booting, there are two choices: loading an operating system
or chainloading
another bootloader. The chainloading
feature of grub loads the bootsector of a partition (that contains an
operating system).
Some older operating systems require a primary partition
that is set as active
. Only one partition can be set
active
so grub
can do this on the fly just before
chainloading
.
This screenshot shows how to set the first primary partition active
with grub
.
root (hd0,0)
makeactive
Chainloading refers to grub loading another operating system\'s
bootloader. The chainloader
switch receives one option:
the number of sectors to read and boot. For DOS
and
OS/2
one sector is enough. Note that DOS
requires the
boot/root partition to be active!
Here is a complete example to chainload
an old operating system.
title MS-DOS 6.22
root (hd0,1)
makeactive
chainloader +1
simple stanza examples
This is a screenshot of a Debian 4
stanza.
title Debian GNU/Linux, kernel 2.6.17-2-686
root (hd0,0)
kernel /boot/vmlinuz-2.6.17-2-686 root=/dev/hda1 ro
initrd /boot/initrd.img-2.6.17-2-686
Here a screenshot of a Red Hat Enterprise Linux 5
stanza.
title Red Hat Enterprise Linux Server (2.6.18-128.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-98.el5 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
initrd /initrd-2.6.18-98.el5.img
editing grub at boot time
At boot time, when the grub
menu is displayed, you can type e
to
edit the current stanza. This enables you to add parameters to the
kernel.
One such parameter, useful when you lost the root password, is single
.
This will boot the kernel in single user mode (although some
distributions will still require you to type the root password.
kernel /boot/vmlinuz-2.6.17-2-686 root=/dev/hda1 ro single
Another option to reset a root password is to use an init=/bin/bash
parameter.
kernel /boot/vmlinuz-2.6.17-2-686 root=/dev/hda1 ro init=/bin/bash
Note that some distributions will disable this option at kernel compile time.
installing grub
Run the grub-install
command to install grub
. The
command requires a destination for overwriting the boot sector
or
mbr
.
# grub-install /dev/hda
You will rarely have to do this manually, since grub is installed when
installing the operating system and does not need any re-install when
changing configuration (as is the case for lilo
).
grub2
grub 2.0 ?
The main configuration file is now /boot/grub/grub.cfg
. And while this
file may look familiar, one should never edit this file directly
(because it is generated!).
root@linux:~# ls -l /boot/grub/grub.cfg
-r--r--r-- 1 root root 2453 May 13 17:22 /boot/grub/grub.cfg
root@linux:~# head -3 /boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
/etc/grub.d/40_custom
The /etc/grub.d/40_custom
file can be changed to include
custom entries. These entries are automatically added to grub.
root@linux:~# ls -l /etc/grub.d/40_custom
-rwxr-xr-x 1 root root 214 Jul 3 2013 /etc/grub.d/40_custom
root@linux:~# cat /etc/grub.d/40_custom
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
/etc/default/grub
The new configuration file for changing grub is now
/etc/default/grub
.
root@linux:~# head /etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX="debian-installer=en_US"
update-grub
Whenever the /etc/default/grub
file is changed, you will need to run
update-grub
to apply the changes.
root@linux:~# vi /etc/default/grub
root@linux:~# update-grub
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.2.0-4-amd64
Found initrd image: /boot/initrd.img-3.2.0-4-amd64
done
lilo
Linux loader
lilo
used to be the most used Linux bootloader, but is
steadily being replaced with grub
and recently grub2
.
lilo.conf
Here is an example of a lilo.conf
file. The delay
switch receives a number in tenths of a second. So the delay below is
three seconds, not thirty!
boot = /dev/hda
delay = 30
image = /boot/vmlinuz
root = /dev/hda1
label = Red Hat 5.2
image = /boot/vmlinuz
root = /dev/hda2
label = S.U.S.E. 8.0
other = /dev/hda4
table = /dev/hda
label = MS-DOS 6.22
The configration file shows three example stanzas. The first one boots Red Hat from the first partition on the first disk (hda1). The second stanza boots Suse 8.0 from the next partition. The last one loads MS-DOS.
practice: bootloader
0. Find out whether your system is using lilo, grub or grub2. Only do the practices that are appropriate for your system.
1. Make a copy of the kernel, initrd and System.map files in /boot. Put the copies also in /boot but replace 2.x or 3.x with 4.0 (just imagine that Linux 4.0 is out.).
2. Add a stanza in grub for the 4.0 files. Make sure the title is different.
3. Set the boot menu timeout to 30 seconds.
4. Reboot and test the new stanza.
solution: bootloader
0. Find out whether your system is using lilo, grub or grub2. Only do the practices that are appropriate for your system.
1. Make a copy of the kernel, initrd and System.map files in /boot. Put the copies also in /boot but replace 2.x or 3.x with 4.0 (just imagine that Linux 4.0 is out.).
[root@linux boot]# uname -r
2.6.32-431.11.2.el6.x86_64
[root@linux boot]# cp System.map-2.6.32-431.11.2.el6.x86_64 System.map-4.0
[root@linux boot]# cp vmlinuz-2.6.32-431.11.2.el6.x86_64 vmlinuz-4.0
[root@linux boot]# cp initramfs-2.6.32-431.11.2.el6.x86_64.img initramfs-4.0\
.img
Do not forget that the initrd (or initramfs) file ends in .img
.
2. Add a stanza in grub for the 4.0 files. Make sure the title is different.
[root@linux grub]# cut -c1-70 menu.lst | tail -12
title CentOS (4.0)
root (hd0,0)
kernel /vmlinuz-4.0 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS L
initrd /initramfs-4.0.img
title CentOS (2.6.32-431.11.2.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.11.2.el6.x86_64 ro root=/dev/mapper/VolGro
initrd /initramfs-2.6.32-431.11.2.el6.x86_64.img
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-lv
initrd /initramfs-2.6.32-431.el6.x86_64.img
[root@linux grub]#
3. Set the boot menu timeout to 30 seconds.
[root@linux grub]# vi menu.lst
[root@linux grub]# grep timeout /boot/grub/grub.conf
timeout=30
4. Reboot and test the new stanza.
[root@linux grub]# reboot
Select your stanza and if it boots then you did it correct.