How does Linux deal with a separate /boot partition?

Here is the problem in your understanding:

My understanding is that the bootloader GRUB2, is mounted to /boot.

GRUB is not "mounted" on boot. GRUB is installed to /boot, and is loaded from code in the Master Boot Record. Here is a simplified overview of the modern boot process, assuming a GNU/Linux distribution with an MBR/BIOS (not GPT/UEFI):

  1. The BIOS loads.
  2. The BIOS loads the small piece of code that is in the Master Boot Record.
  3. GRUB does not fit in 440 bytes, the size of the Master Boot Record. Therefore, the code that is loaded actually just parses the partition table, finds the /boot partition (which I believe is determined when you install GRUB to the Master Boot Record), and parses the filesystem information. It then loads Stage 2 GRUB. (This is where the simplification comes in.)
  4. Stage 2 GRUB loads everything it needs, including the GRUB configuration, then presents a menu (or not, depending on user configuration).
  5. A boot sequence is chosen. This could be by a timeout, by the user selecting a menu entry, or by booting a command list.
  6. The boot sequence starts executing. This can do a number of things - for example, loading a kernel, chainloading to another bootloader - but let's assume that the boot sequence is standard GNU/Linux.
  7. GRUB loads the Linux kernel.
  8. GRUB loads the initial ramdisk.
  9. The initial ramdisk mounts / under /new_root (possibly cryptographically unlocking it), starts udev, starts resume-from-swap, etc.
  10. The initial ramdisk uses the pivot_root utility to set /new_root as the real /.
  11. init starts. Partitions get mounted, daemons get started, and the system boots.

Notice how the kernel is only loaded at step 7. Because of this, there is no concept of mounting until step 7. This is why /boot has to be mounted again in step 9, even though GRUB has already used it.

It may also be of use to look at the GRUB 2 section of the Wikipedia page on GRUB.


Linux (the kernel) does not care how many boot partitions you have. Loading the kernel from disk is the job of the bootloader (e.g. grub, grub2, lilo) and these tools also do not care about the number of locations a kernel might be located. They only care about the specific location.

As an example, my boot partition is /dev/md1, which is a mdadm RAID mirror backed by the physical partitions /dev/sde1 and /dev/sdf1. I can mount these individually if I wanted and as such this technically counts as having two boot partitions, though they should contain the same data.

Having two partitions for /boot for me is an availability issue, but they could equally be different /boot partitions. The next step to is how does the bootloader know? Here is how:

menuentry 'Linux 3.10.17 (sde) kernel-3.10.17-g' {
        root=hd0,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3
        initrd /boot/initrd-3.10.17-g
}

menuentry 'Linux 3.10.17 (sdf) kernel-3.10.17-g' {
        root=hd1,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3 
        initrd /boot/initrd-3.10.17-g
}

This is an excerpt from a grub2 configuration and you'll note that the only differences are root=hd0,1 and root=hd1,1 which establish which boot partition that entry references.


Now to walk you though a boot so you can understand what is going on here.

  • The BIOS reads the MBR from the boot volume and jumps to the bootloader
  • The bootloader (e.g. grub2) is configured to know which device and partition contains your kernel. Grub2 accesses this partition directly and loads your kernel into memory.
  • Your bootloader then jumps into the kernel and the kernel boots your machine.

The bootloader doesn't care how many boot partitions you have, it only cares where they are and you must tell it that information.

The kernel doesn't care how many boot partitions you have, because it never needs to see them (you only need to have it available to add new kernels for example).


Question #1

My understanding is that the bootloader GRUB2, is mounted to /boot. When the directory /boot is on separate partition sda2, however, how is it that this can happen before / is actually mounted?

I don't think you're understanding is quite right here. From the GNU GRUB Wikipedia page:

excerpt

When a computer is turned on, the computer's BIOS finds the configured primary bootable device (usually the computer's hard disk) and loads and executes the initial bootstrap program from the master boot record (MBR). The MBR is the first sector of the hard disk, and has the number 0 (sectors counting starts at 0). For a long time, the size of a sector has been 512 bytes, but since 2009 there are hard disks available with a sector size of 4096 bytes, called Advanced Format disks. As of October 2013, such hard disks are still accessed in 512-byte sectors, by utilizing the 512e emulation.

In GRUB version 2 the following takes place:

excerpt

Booting the Computer

When power is turned on, the following happens:

  • The hardware initializes, sets the CPU to real mode (no virtual memory) and jumps to fixed location 0xFFFF0 (hardwired in the CPU circuits)
  • BIOS code stored in a ROM or flash-memory mapped to that location is therefore executed.
  • The BIOS code looks at the BIOS config data to see which is the boot device. This BIOS config data can usually be edited by pressing some special key-sequence just after turning the power on, causing the BIOS configuration program to run. Among other things, the boot device can usually be selected here.
  • The BIOS code loads the MBR of the boot device into RAM. Remember that an MBR is just 512 bytes! The loaded data is of course the program & data that grub-install dynamically created and wrote there when the grub-install program was executed.
  • The BIOS code jumps to the start address of the loaded MBR (ie Grub code executes for the first time since power-on).
  • Grub’s MBR code loads a single sector whose address is hard-wired into the MBR block. It then loops over the (address,len) pairs in that sector loading all that data from the disk into memory (ie loads the contents of file /boot/grub/core.img, or its “embedded” copy). The MBR code then jumps to the loaded code, ie “executes” the program in core.img.
  • As described in the “Installing Grub” section, this trick of embedding the raw disk block addresses makes it possible to store core.img in space that is not in a partition, and that has never been formatted as a filesystem at all (“embedding”). And in this case, if core.img is modified, as long as the new version is “embedded” at the same location, the MBR code does not need to be updated.
  • Alternatively, it is possible for the core.img to be inside a real filesystem, and for Grub to read the core.img file contents without having a driver for that filesystem. However in this case, if core.img is modified then the first block of the file may well be given a new address on disk; if this happens then the MBR must be updated to point to this new location. Nevertheless, as core.img is usually updated by running grub-install, this is not usually a problem.
  • Note that theoretically, if core.img is on a different device than the MBR, and new hardware is added then the Grub-generated MBR record might not be able to correctly load the core.img file; the device-id on which the first sector of core.img is to be found is hard-wired into the MBR, not searched for. However there is no solution for this; there is no way to embed the equivalent of the Grub “search” command into the 512-byte MBR. This problem is not likely though; normally the core.img is embedded on the same device as the MBR. And once core.img has been loaded it can use search.mod to find all further /boot/grub files, and is therefore immune to hardware rearrangements.
  • The executed core.img code now initializes all the modules that are built into it (linked into core.img); one of these modules will be a filesystem driver capable of reading the filesystem on which directory /boot/grub lives.
  • It also registers a set of built-in commands: set, unset, ls, insmod.
  • If a “config file” has been linked into core.img, this is then passed to a very simple build-in script parser for processing. Scripting commands in the config file can only invoke built-in or linked-in commands. Simple scenarios (eg booting a typical desktop computer from a local drive) need no config file; this facility is used for things like booting via pxe, remote nfs or when /boot/grub is on an LVM device.
  • Core.img now loads file “/boot/grub/normal.mod” dynamically from disk, and jumps to its entry function. Note that this step requires the appropriate filesystem driver to be set up (ie built-in).

     ss of boot process

NOTE: When you see the typical GRUB2 menu where you select which OS/Kernel to boot, you're referencing the system's /boot/grub directory at this point.

                                         ss of grub tui

References

  • Booting Linux on x86 using Grub2
  • GNU GRUB - Wikipedia
  • 6 Stages of Linux Boot Process (Startup Sequence)
  • Inside the Linux boot process
  • Linux startup process
  • GRUB 2 bootloader - Full tutorial - Dedoimedo