Linux boot process

From Smop.co.uk

Jump to: navigation, search

These are some notes I've made whilst cloning machines and setting up root RAID systems (where / is a RAID device). I'll try and explain everything, however sometimes the explanation may come further down the page. If I explained everything in order it might take a few pages to get to the good stuff :-)

If you are having bad problems booting, you can try booting into single user mode (add single as a boot parameter - for example at a LILO boot prompt you might type "linux single" rather than picking the default linux selection).

Contents

Rescue (Boot) disks

If this doesn't work, then you need a boot disk - I use one of three different ones depending upon circumstances:

  1. Knoppix is a Debian based boot CD which runs Linux from the boot disk - it's compressed and so has around 2GB of programs on it. This makes Knoppix the best choice if you have a copy already downloaded. I boot the CD using the command line "knoppix 2" as this skips the graphical KDE session and speeds things up alot. Once loaded I use "loadkeys uk" to load the correct keyboard map and "setterm -blength 0" to turn the keyboard beep off. Note: Knoppix currently (v3.8) does not support LVM.
  2. LNX-BBC is a bootable mini-CD (the 50MB variety, not the 30MB variety!). Second choice - hopefully small enough to download in an emergency and burn onto a CD (it will work on a normal sized CD, it's just more cute on a mini-CD).
  3. Tomsrtbt is a bootable floppy disk. So it's the smallest of the lot - nice and fast to download, but more limited than the rest.

If you are merely missing a kernel image, you can try booting your system using the kernel from the boot disk: "linux root=/dev/hda1" for instance.

Disk and partition names

For a full and accurate view of this, see the start of the LILO manual.

There are generally only two kinds of disk on Linux - IDE (normal) and SCSI (high-end). SCSI disks are named sda, sdb and so on. IDE disks are called hda, hdb etc.

SCSI disks are just named in the order in which they are seen, however IDE disks have a more fixed naming convention. IDE consists of a number of channels (typically two on the motherboard), each channel can have two devices on it - a master (which should be on the end of the cable) and an optional slave (which should be half-way along the cable). In this way we get the table below:

Name IDE Channel Type Typically
hda 0 master hard disk
hdb 0 slave (2nd hard disk)
hdc 1 master CD-ROM
hdd 1 slave empty

In the early days, DOS allowed a disk to be divided into upto four pieces (called partitions) - hda1 would be the first parition on hda, hdc3 would be the third partition on hdc.

This was too restrictive and so one partition - called the extended partition could be subdivided into upto 12 even smaller logical partitions (numbered in Linux from 5 upwards). The other "main" partitions were called primary paritions. Unless you are using LVM or RAID, each partition will generally correspond to a filesystem. In pictorial format:

partition physical layout filesytem
hda1 hda1 Windows C:
hda2 hda2 Linux /
hda3 hda5 Linux /var
hda3 hda6 Windows D:
hda3 hda7 OpenBSD
hda3 - Free
hda4 hda4 Linux swap

In this example, hda3 encompasses three logical partitions (or rather two and some free space).

PC Boot process

For a full and accurate view of this, see the start of the LILO manual.

When a PCs boots, it normally has a look at the BIOS settings to see what it should boot from. These days this is typically a list including floppy, CD-ROM, the first hard disk and even the network.

We are probably only really concerned with booting from hard disk, so let's dig into that. Right at the very, very start of a hard disk is a small area called the "Master Boot Record" or MBR. There is also a little boot sector for each of the partitons (although some programs don't like those for thelogical partitions).

The PC reads the MBR and runs the code it finds there. Since the MBR is very small, the program in the MBR normally just jumps somewhere else on the disk and runs a bigger program from there. Some programs (GRUB) have an intelligent MBR program that can actually figure out where the big program (generally known as the second stage loader) lives. Other programs - noticeably LILO, just store the location of the second stage loader. If it moves for any reason, LILO won't boot (see near the end of the manual for "LI" etc.

The second stage will then generally read a configuration file - perhaps displaying a list of operating systems that you can boot from. You pick your operating systems and then typically one of two things will happen:

  • if it's Linux, then it will load your kernel (e.g. /boot/vmlinux and give it some instructions on how to boot
  • if it's Windows, then it will just execute the boot sector for that partition (e.g. hda1 in the earlier example).


Linux boot process

I'll start with a simplified list:

  1. lilo MBR
  2. lilo 2nd stage loader
  3. Linux kernel
  4. initial ramdisk (initrd) loaded
  5. linuxrc script in ramdisk run
  6. root filesystem mounted
  7. boot scripts run

The initial ramdisk is used in more complicated setup (generally SCSI installations and vendor provided kernels). The Linux kernel is quite modular and so instead of using one large kernel, it's common to split bits off into modules. For instance why have fourty SCSI drivers loaded if youonly use one? However what if that SCSI driver is used for your root filesystem?

To fix this, you can create a ramdisk (the initrd) with all these useful bits in and then use that right at the start of the boot process. The linuxrc script in the initrd will also be run. This can be used to do things like start RAID devices etc. More detail in a later section.

In the last section I was a bit vague saying that "it will give it some instructions on how to boot". In fact, each Linux kernel image has some compiled in defaults (which you can change using the "rdev" tool). The most important parameter is the root option which says where the root filesystem is (/dev/hda2 in our earlier example).

Lilo

Let's start with a typical lilo configuration file (/etc/lilo.conf):

# Remeber to rerun lilo after any changes

lba32
compact

# vga=ask, vga=normal, vga=9
vga=normal

boot=/dev/hda
root=/dev/hda2

#append=""

# in deciseconds (0.1s)
delay=40

# Boot up Linux by default.
default=Linux

image=/vmlinuz
  label=Linux
  read-only
  alias=l
                   image=/vmlinuz.old
  label=LinuxOLD
  read-only
  optional
  alias=o
                                                        
other=/dev/hda1
  label=Windoze
  alias=w
                                        
other=/dev/hda7
  label=FreeBSD
  alias=b
  • lba32 means lilo will work with large disks,
  • compact speeds the boot process - I've never seen a problem using this.
  • vga option specifies which vga mode to use (various numbers will change the number of rows and columns you get at a text console).
  • boot section says where to install lilo. If you are using Lilo to control what your machine boots, this will be the name of your first hard disk (e.g. /dev/hda), if you are just using it as a second boot loader and using something else to control your machine then you probably just want your Linux partition (e.g. /dev/hda2).
  • root section just says what to use as a root filesystem - /dev/hda2 in our case.
  • append specifies any extra parameters to pass to the kernel.

The next two options allow you to specify a default choice that is chosen if the user doesn't interrupt by pressing a key quickly enough (4 seconds in this case).

The next paragraph is our first boot option - we've specified a Linux kernel image (/vmlinux - this can be a symlink), a name or label for it and a shorter alias for it. I'll explain why we need read-only shortly. The next paragraph is nearly identical, except that it has an optional keyword which means that lilo won't object if it's missing.

The next two paragraphs show how to boot other operating systems - in this case lilo will just execute the boot sectors in /dev/hda1 and /dev/hda7 respectively.

When Linux is started, it will generally carry out filesystem checks before using the filesystems - / is done first, then the other filesystems are done in parallel. However the filesystems cannot be read/write whilst they are being checked (as any fixes would require low-level writing to a live filesystem), therefore the process is:

  1. mount / filesystem read-only
  2. fsck / filesystem
  3. remount / filesystem read-write
  4. fsck all other filesystems
  5. carry on booting

... and thats why we need read-only in the /etc/lilo.conf file (the corresponding kernel parameter is ro by the way).

You can specify an initial ramdisk to use by adding a line such as "initrd=/boot/initrd" to a Linux paragraph. That's more or less Lilo done and dusted.

There is one critical item to remember about Lilo - it uses absolute disk addresses for anything useful (which it stores in a map file) - so if you change where /vmlinuz is, or where /bin/lilo (the second stage loader) is (e.g. you install a new kernel or a new version of lilo), you must rerun lilo or next time you boot you will almost certainly get a LI display or something similar. Boot off a rescue disk and rerun lilo (see the example later on).

Initial ramdisks (initrd)

The initial ramdisk is not complicated, however it is one extra step so if you don't need it, why bother? If you do need it or you are just stuborn or curious, read on...

In initial ramdisk is really just another disk - albeit one that instead of occupying a whole disk partition, just occupies a file. It is then compressed with the gzip algorithm. On Linux, you can pretend that a file is a device by using a "-o loop" combination with the mount command:

localhost:/tmp # file initrd 
initrd: gzip compressed data, deflated, original filename, initrd_small'',
last modified: Tue Jul  8 15:26:35 2003, max compression, os: Unix
localhost:/tmp # mv initrd initrd.gz
localhost:/tmp # gunzip initrd.gz 
localhost:/tmp # file initrd 
initrd: Linux rev 1.0 ext2 filesystem data
localhost:/tmp # mount -o loop initrd  loop
localhost:/tmp # ls loop
.  ..  bin  dev  lib  linuxrc

The linuxrc script can do whatever you like - but ensure that you have included any needed binaries. Typically linuxrc begins "#!/bin/sh". It will therefore be read by the program in /bin/sh that is in the ramdisk - this is likely to be a non-standard shell - possibly one called "nash".

The only thing I've had to do with initrd has been on SuSE Linux - I edited /etc/sysconfig/kernel and added the kernel modules I needed (without the trailing ".o") to the INITRD_MODULES variable. You will need the modules for your SCSI controllers, any RAID modules (such as "raid1") and non-ext2 filesystems such as ext3 and reiserfs.

The next step on SuSE is to run mkinitrd which calculates any other needed modules and builds an initrd for each kernel image in /boot. Then you rerun lilo :-)

Full details of the initrd are in the Linux kernel source tree in <a href="/links/initrd.txt">Documentation/initrd.txt</a>.


WRITEN UP TO HERE


grub

chroot, lilo -r, or "linux root=/dev/hda1^X"

/etc/fstab, check partition, FS type, if ext3, ensure journal (tune2fs -j write one ifthere isnt or will complain)

stat, hex->dec conversion, (and /proc/sys/kernel/real-root-dev)

/etc/raidtab, partition type = FD for autodetect, append md=0,/dev/..,...

1024 cylinders

links, references

Personal tools