Sunday, January 19, 2014

Multiboot Specification and limitations (Bootloader -> OS)

Typically in a computer system, the boot sequence is like this: firmware -> bootloader -> Operating System.  The problem is that nowadays we have the largest variety of operating systems, boot loaders, and firmwares (UEFI/Legacy), and even some of them are proprietary software that are not public. So, the interaction might be a problem if the interface is not well-defined. 

Multiboot Specification specifies an interface between a bootloader and a operating system, such that any complying boot loader should be able to load any complying operating system, because it provides a standard means for the communications between the bootloader and operating system software. According to this specification, it defines an interface in these three main aspects: 
  • Multiboot header: The format of an OS image as seen by a boot loader. A MB-compliant boot loader can search this header to determine how to load the OS image, and where to jump (the location of the entry point).
  • Initial processor states: The state of a machine when a boot loader starts an OS. The specification defines the processor state before transferring to OS.
  • Multiboot information structure: The format of boot information passed by a boot loader to an OS. e.g. such an information structure may contains memory map(e820 map), modules(like bzImage, initrd), UEFI information, cmdline options etc..
Currently there are some system software that are using Multiboot protocols, e.g. Trusted Boot (tboot, using Intel(R) Trusted Execution Technology to perform a measured and verified launch for an OS kernel and or VMM), lk (Little Kernel, a little embedded kernel), XEN hypervisor (link). however, most of modern complex operating systems (e.g. Windows, FreeBSD, Linux) are still using their own boot specifications. For example, Linux community defines Linux Boot Protocol (link), which is widely used by Ubuntu, Redhat, Android, etc.. and it supports different platforms (x86, ARM, 32bit/64bit) with different firmwares and bootloaders. 

GRUB 2 (GRand Unified Bootloader) is one that is a multiboot-compliant bootloader. It can boot any multiboot-compliant operating systems. And as an OS image, GRUB2 itself is also multiboot-compliant, which means it can be booted by itself and any other multiboot-compliant bootloaders. Tboot has the similar capabilities.


Multiboot Specification currently has two major different versions, see the links below.
  1. MB version 0.6.96: http://www.gnu.org/software/grub/manual/multiboot/multiboot.html
  2. MB version 1.6: http://nongnu.askapache.com/grub/phcoder/multiboot.pdf
The implementation of second version specification is significantly different with that of the first version. It is more extensible with various TAG based structures for interface communications between bootloader and OS image. For example, it adds new TAG type for UEFI (32bit/64bit) support to pass UEFI System Table Pointer, so that the operating system can get UEFI information like UEFI boot services, runtime services information and ACPI tables.

Note that an OS image can embed both Multiboot 1 and Multiboot 2 header into a single image, however, basically the bootloader should provide a configuration mechanism to let users select which version of header (boot specification) will be used. 


However, there is still a limitation:

  • It doesn't define 64bit entry points, and doesn't define the 64bit processor handoff states. In reality, this introduces some issues in some special case. for example, when the Bootloader is 64bit and the OS image is also 64bit, then if both bootloader and OS are multiboot-compliant, the extra code logics must be introduced: 1) for bootloader, it must have to do processor mode switch from 64bit to 32bit in order to call the 32bit entry of OS image, and 2) for OS, it must also have to add a similar code stub to do processor mode in reverse order. 
Besides, it defines the handoff behavior JMP, which means that when bootloader transfers control to OS, it never returns back because the behaviors of returning back is undefined in the multiboot specification. But in a real world there are some situations that such a return is required, for example, we want to boot a pre-OS software after bootloader, then tell bootloader continue to boot the OS software. In this case, the boot sequence is like this: firmware -> bootloader -> pre-OS software -> Operating System. XEN hypervisor and tboot are just samples for this sequence. In this sequence the pre-OS software must be capable of launching OS software, actually it behaves as the "bootloader" of the OS software. 

<The End>

No comments:

Post a Comment