1--- 2title: Boot Loader Specification 3category: Booting 4layout: default 5SPDX-License-Identifier: LGPL-2.1-or-later 6--- 7 8# The Boot Loader Specification 9 10_TL;DR: Currently there's no common boot scheme across architectures and 11platforms for open-source operating systems. There's also little cooperation 12between multiple distributions in dual-boot (or triple, … multi-boot) 13setups. We'd like to improve this situation by getting everybody to commit to a 14single boot configuration format that is based on drop-in files, and thus is 15robust, simple, works without rewriting configuration files and is free of 16namespace clashes._ 17 18The Boot Loader Specification defines a scheme how different operating systems 19can cooperatively manage a boot loader configuration directory, that accepts 20drop-in files for boot menu items that are defined in a format that is shared 21between various boot loader implementations, operating systems, and userspace 22programs. The same scheme can be used to prepare OS media for cases where the 23firmware includes a boot loader. The target audience for this specification is: 24 25* Boot loader developers, to write a boot loader that directly reads its 26 configuration at runtime from these drop-in snippets 27* Firmware developers, to add generic boot loading support directly to the 28 firmware itself 29* Distribution and Core OS developers, in order to create these snippets at 30 OS/kernel package installation time 31* UI developers, for implementing a user interface that discovers the available 32 boot options 33* OS Installer developers, to prepare their installation media and for setting 34 up the initial drop-in directory 35 36## Why is there a need for this specification? 37 38Of course, without this specification things already work mostly fine. But here's why we think this specification is needed: 39 40* To make the boot more robust, as no explicit rewriting of configuration files 41 is required any more 42* To allow an out of the box boot experience on any platform without the need 43 of traditional firmware mechanisms (e.g. BIOS calls, UEFI Boot Services) 44* To improve dual-boot scenarios. Currently, multiple Linux installations tend 45 to fight over which boot loader becomes the primary one in possession of the 46 MBR, and only that one installation can then update the boot loader 47 configuration of it freely. Other Linux installs have to be manually 48 configured to never touch the MBR and instead install a chain-loaded boot 49 loader in their own partition headers. In this new scheme as all 50 installations share a loader directory no manual configuration has to take 51 place, and all participants implicitly cooperate due to removal of name 52 collisions and can install/remove their own boot menu entries at free will, 53 without interfering with the entries of other installed operating systems. 54* Drop-in directories are otherwise now pretty ubiquitous on Linux as an easy 55 way to extend configuration without having to edit, regenerate or manipulate 56 configuration files. For the sake of uniformity, we should do the same for 57 extending the boot menu. 58* Userspace code can sanely parse boot loader configuration which is essential 59 with modern BIOSes which do not necessarily initialize USB keyboards anymore 60 during boot, which makes boot menus hard to reach for the user. If userspace 61 code can parse the boot loader configuration, too, this allows for UIs that 62 can select a boot menu item to boot into, before rebooting the machine, thus 63 not requiring interactivity during early boot. 64* To unify and thus simplify configuration of the various boot loaders around, 65 which makes configuration of the boot loading process easier for users, 66 administrators and developers alike. 67* For boot loaders with configuration _scripts_ such as grub2, adopting this 68 spec allows for mostly static scripts that are generated only once at first 69 installation, but then do not need to be updated anymore as that is done via 70 drop-in files exclusively. 71 72## Why not simply rely on the EFI boot menu logic? 73 74EFI is not ubiquitous, especially not in embedded systems. If you have an EFI 75system, it provides a boot options logic that can offer similar 76functionality. Here's why we think that it is not enough for our uses: 77 78* The various EFI implementations implement the boot order/boot item logic to 79 different levels. Some firmware implementations do not offer a boot menu at 80 all and instead unconditionally follow the EFI boot order, booting the first 81 item that is working. 82* If the firmware setup is used to reset all data usually all EFI boot entries 83 are lost, making the system entirely unbootable, as the firmware setups 84 generally do not offer a UI to define additional boot items. By placing the 85 menu item information on disk, it is always available, regardless if the BIOS 86 setup data is lost. 87* Harddisk images should be movable between machines and be bootable without 88 requiring explicit EFI variables to be set. This also requires that the list 89 of boot options is defined on disk, and not in EFI variables alone. 90* EFI is not universal yet (especially on non-x86 platforms), this 91 specification is useful both for EFI and non-EFI boot loaders. 92* Many EFI systems disable USB support during early boot to optimize boot 93 times, thus making keyboard input unavailable in the EFI menu. It is thus 94 useful if the OS UI has a standardized way to discover available boot options 95 which can be booted to. 96 97## Technical Details 98 99Everything described below is located on a placeholder file system `$BOOT`. The 100installer program should pick `$BOOT` according to the following rules: 101 102* On disks with an MBR partition table: 103 * If the OS is installed on a disk with an MBR partition table, and a 104 partition with the type id of 0xEA already exists it should be used as 105 `$BOOT`. 106 * Otherwise, if the OS is installed on a disk with an MBR partition table, a 107 new partition with type id of 0xEA shall be created, of a suitable size 108 (let's say 500MB), and it should be used as `$BOOT`. 109* On disks with GPT (GUID Partition Table) 110 * If the OS is installed on a disk with GPT, and an Extended Boot Loader 111 Partition (or XBOOTLDR partition for short), i.e. a partition with GPT type 112 GUID of `bc13c2ff-59e6-4262-a352-b275fd6f7172`, already exists, it should 113 be used as `$BOOT`. 114 * Otherwise, if the OS is installed on a disk with GPT, and an EFI System 115 Partition (or ESP for short), i.e. a partition with GPT type UID of 116 `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` already exists and is large enough 117 (let's say 250MB) and otherwise qualifies, it should be used as `$BOOT`. 118 * Otherwise, if the OS is installed on a disk with GPT, and if the ESP 119 already exists but is too small, a new suitably sized (let's say 500MB) 120 XBOOTLDR partition shall be created and used as `$BOOT`. 121 * Otherwise, if the OS is installed on a disk with GPT, and no ESP exists 122 yet, a new suitably sized (let's say 500MB) ESP should be created and used 123 as `$BOOT`. 124 125This placeholder file system shall be determined during _installation time_, 126and an fstab entry may be created. It should be mounted to either `/boot/` or 127`/efi/`. Additional locations like `/boot/efi/` (with `/boot/` being a separate 128file system) might be supported by implementations. This is not recommended 129because the mounting of `$BOOT` is then dependent on and requires the mounting 130of the intermediate file system. 131 132**Note:** _`$BOOT` should be considered **shared** among all OS installations 133of a system. Instead of maintaining one `$BOOT` per installed OS (as `/boot/` 134was traditionally handled), all installed OS share the same place to drop in 135their boot-time configuration._ 136 137For systems where the firmware is able to read file systems directly, `$BOOT` 138must be a file system readable by the firmware. For other systems and generic 139installation and live media, `$BOOT` must be a VFAT (16 or 32) file 140system. Applications accessing `$BOOT` should hence not assume that fancier 141file system features such as symlinks, hardlinks, access control or case 142sensitivity are supported. 143 144This specification defines two types of boot loader entries. The first type is 145text based, very simple and suitable for a variety of firmware, architecture 146and image types ("Type #1"). The second type is specific to EFI, but allows 147single-file images that embed all metadata in the kernel binary itself, which 148is useful to cryptographically sign them as one file for the purpose of 149SecureBoot ("Type #2"). 150 151Not all boot loader entries will apply to all systems. For example, Type #1 152entries that use the `efi` key and all Type #2 entries only apply to EFI 153systems. Entries using the `architecture` key might specify an architecture that 154doesn't match the local one. Boot loaders should ignore all entries that don't 155match the local platform and what the boot loader can support, and hide them 156from the user. Only entries matching the feature set of boot loader and system 157shall be considered and displayed. This allows image builders to put together 158images that transparently support multiple different architectures. 159 160Note that the `$BOOT` partition is not supposed to be exclusive territory of 161this specification. This specification only defines semantics of the `/loader/` 162directory inside the file system (see below), but it doesn't intend to define 163ownership of the whole file system exclusively. Boot loaders, firmware, and 164other software implementing this specification may choose to place other 165files and directories in the same file system. For example, boot loaders that 166implement this specification might install their own boot code into the `$BOOT` 167partition. On systems where `$BOOT` is the ESP this is a particularly common 168setup. Implementations of this specification must be able to operate correctly 169if files or directories other than `/loader/` are found in the top level 170directory. Implementations that add their own files or directories to the file 171systems should use well-named directories, to make name collisions between 172multiple users of the file system unlikely. 173 174### Type #1 Boot Loader Specification Entries 175 176We define two directories below `$BOOT`: 177 178* `$BOOT/loader/` is the directory containing all files needed for Type #1 179 entries 180 181* `$BOOT/loader/entries/` is the directory containing the drop-in 182 snippets. This directory contains one `.conf` file for each boot menu item. 183 184**Note:** _In all cases the `/loader/` directory should be located directly in 185the root of the file system. Specifically, if `$BOOT` is the ESP, then 186`/loader/` directory should be located directly in the root directory of the 187ESP, and not in the `/EFI/` subdirectory._ 188 189Inside the `$BOOT/loader/entries/` directory each OS vendor may drop one or 190more configuration snippets with the suffix ".conf", one for each boot menu 191item. The file name of the file is used for identification of the boot item but 192shall never be presented to the user in the UI. The file name may be chosen 193freely but should be unique enough to avoid clashes between OS 194installations. More specifically it is suggested to include the machine ID 195(`/etc/machine-id` or the D-Bus machine ID for OSes that lack 196`/etc/machine-id`), the kernel version (as returned by `uname -r`) and an OS 197identifier (The ID field of `/etc/os-release`). Example: 198`$BOOT/loader/entries/6a9857a393724b7a981ebb5b8495b9ea-3.8.0-2.fc19.x86_64.conf`. 199 200In order to maximize compatibility with file system implementations and 201restricted boot loader environments, and to minimize conflicting character use 202with other programs, file names shall be chosen from a restricted character 203set: ASCII upper and lower case characters, digits, "+", "-", "_" and 204".". Also, the file names should have a length of at least one and at most 255 205characters (including file name suffix). 206 207These configuration snippets shall be Unix-style text files (i.e. line 208separation with a single newline character), in the UTF-8 encoding. The 209configuration snippets are loosely inspired on Grub1's configuration 210syntax. Lines beginning with '#' shall be ignored and used for commenting. The 211first word of a line is used as key and shall be separated by one or more 212spaces from its value. The following keys are known: 213 214* `title` shall contain a human readable title string for this menu item. This 215 will be displayed in the boot menu for the item. It is a good idea to 216 initialize this from the `PRETTY_NAME` of `/etc/os-release`. This name should 217 be descriptive and does not have to be unique. If a boot loader discovers two 218 entries with the same title it is a good idea to show more than just the raw 219 title in the UI, for example by appending the `version` field. This field is 220 optional. Example: "Fedora 18 (Spherical Cow)". 221* `version` shall contain a human readable version string for this menu 222 item. This is usually the kernel version and is intended for use by OSes to 223 install multiple kernel versions at the same time with the same `title` 224 field. This field shall be in a syntax that is useful for Debian-style 225 version sorts, so that the boot loader UI can determine the newest version 226 easily and show it first or preselect it automatically. This field is 227 optional. Example: `3.7.2-201.fc18.x86_64`. 228* `machine-id` shall contain the machine ID of the OS `/etc/machine-id`. This 229 is useful for boot loaders and applications to filter out boot entries, for 230 example to show only a single newest kernel per OS, or to group items by OS, 231 or to maybe filter out the currently booted OS in UIs that want to show only 232 other installed operating systems. This ID shall be formatted as 32 lower 233 case hexadecimal characters (i.e. without any UUID formatting). This key is 234 optional. Example: `4098b3f648d74c13b1f04ccfba7798e8`. 235* `sort-key` shall contain a short string used for sorting entries on 236 display. This can be defined freely though should typically be initialized 237 from `IMAGE_ID=` or `ID=` from `/etc/os-release` of the relevant entry, 238 possibly suffixed. This field is optional. If set, it is used as primary 239 sorting key for the entries on display (lexicographically increasing). It 240 does not have to be unique (and usually is not). If non-unique the the 241 `machine-id` (lexicographically increasing) and `version` (lexicographically 242 decreasing, i.e. newest version first) fields described above are used as 243 secondary/ternary sorting keys. If this field is not set entries are 244 typically sorted by the `.conf` file name of the entry. 245* `linux` refers to the Linux kernel to spawn and shall be a path relative to 246 `$BOOT`. It is recommended that every distribution creates a machine id and 247 version specific subdirectory below `$BOOT` and places its kernels and 248 initial RAM disk images there. Example: 249 `/6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux`. 250* `initrd` refers to the initrd to use when executing the kernel. This also 251 shall be a path relative to `$BOOT`. This key is optional. This key may 252 appear more than once in which case all specified images are used, in the 253 order they are listed. Example: 254 `6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd`. 255* `efi` refers to an arbitrary EFI program. This also takes a path relative to 256 `$BOOT`. If this key is set, and the system is not an EFI system this entry 257 should be hidden. 258* `options` shall contain kernel parameters to pass to the Linux kernel to 259 spawn. This key is optional and may appear more than once in which case all 260 specified parameters are used in the order they are listed. 261* `devicetree` refers to the binary device tree to use when executing the 262 kernel. This also shall be a path relative to `$BOOT`. This key is 263 optional. Example: 264 `6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.armv7hl/tegra20-paz00.dtb`. 265* `devicetree-overlay` refers to a list of device tree overlays that should be 266 applied by the boot loader. Multiple overlays are separated by spaces and 267 applied in the same order as they are listed. This key is optional but 268 depends on the `devicetree` key. Example: 269 `/6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_A.dtbo 270 /6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_B.dtbo` 271* `architecture` refers to the architecture this entry is defined for. The 272 argument should be an architecture identifier, using the architecture 273 vocabulary defined by the EFI specification (i.e. `IA32`, `x64`, `IA64`, 274 `ARM`, `AA64`, …). If specified and this does not match (case insensitively) 275 the local system architecture this entry should be hidden. 276 277Each configuration drop-in snippet must include at least a `linux` or an `efi` 278key and is otherwise not valid. Here's an example for a complete drop-in file: 279 280 # /boot/loader/entries/6a9857a393724b7a981ebb5b8495b9ea-3.8.0-2.fc19.x86_64.conf 281 title Fedora 19 (Rawhide) 282 sort-key fedora 283 machine-id 6a9857a393724b7a981ebb5b8495b9ea 284 version 3.8.0-2.fc19.x86_64 285 options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 286 architecture x64 287 linux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux 288 initrd /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd 289 290On EFI systems all Linux kernel images should be EFI images. In order to 291increase compatibility with EFI systems it is highly recommended only to 292install EFI kernel images, even on non-EFI systems, if that's applicable and 293supported on the specific architecture. 294 295Conversely, in order to increase compatibility it is recommended to install 296generic kernel images that make few assumptions about the firmware they run on, 297i.e. it is a good idea that both images shipped as UEFI PE images and those 298which are not don't make unnecessary assumption on the underlying firmware, 299i.e. don't hard depend on legacy BIOS calls or UEFI boot services. 300 301Note that these configuration snippets may only reference kernels (and EFI 302programs) that reside on the same file system as the configuration snippets, 303i.e. everything referenced must be contained in the same file system. This is 304by design, as referencing other partitions or devices would require a 305non-trivial language for denoting device paths. If kernels/initrds are to be 306read from other partitions/disks the boot loader can do this in its own native 307configuration, using its own specific device path language, and this is out of 308focus for this specification. More specifically, on non-EFI systems 309configuration snippets following this specification cannot be used to spawn 310other operating systems (such as Windows). 311 312Unfortunately, there are implementations of boot loading infrastructure that 313are also using the /loader/entries/ directory, but place files in them that are 314not valid by this specification. In order to minimize confusion a boot loader 315implementation may place a file /loader/entries.srel next to the 316/loader/entries/ directory containing the ASCII string "type1" (suffixed 317with a UNIX newline). Tools that need to determine whether an existing 318directory implements the semantics described here may check for this file and 319contents: if it exists and contains the mentioned string, it shall assume a 320standards compliant implementation is in place. If it exists but contains a 321different string it shall assume non-standard semantics are implemented. If the 322file does not exist no assumptions should be made. 323 324### Type #2 EFI Unified Kernel Images 325 326A unified kernel image is a single EFI PE executable combining an EFI stub 327loader, a kernel image, an initramfs image, and the kernel command line. See 328the description of the `--uefi` option in 329[dracut(8)](http://man7.org/linux/man-pages/man8/dracut.8.html). Such unified 330images will be searched for under `$BOOT/EFI/Linux/` and must have the 331extension `.efi`. Support for images of this type is of course specific to 332systems with EFI firmware. Ignore this section if you work on systems not 333supporting EFI. 334 335Type #2 file names should be chosen from the same restricted character set as 336Type #1 described above (but use a different file name suffix of `.efi` instead 337of `.conf`). 338 339Images of this type have the advantage that all metadata and payload that makes 340up the boot entry is monopolized in a single PE file that can be signed 341cryptographically as one for the purpose of EFI SecureBoot. 342 343A valid unified kernel image must contain two PE sections: 344 345* `.cmdline` section with the kernel command line 346* `.osrel` section with an embedded copy of the 347 [os-release](https://www.freedesktop.org/software/systemd/man/os-release.html) 348 file describing the image 349 350The `PRETTY_NAME=` and `VERSION_ID=` fields in the embedded os-release file are 351used the same as `title` and `version` in the "boot loader specification" 352entries. The `.cmdline` section is used instead of the `options` field. `linux` 353and `initrd` fields are not necessary, and there is no counterpart for the 354`machine-id` field. 355 356On EFI, any such images shall be added to the list of valid boot entries. 357 358### Additional notes 359 360Note that these configurations snippets do not need to be the only 361configuration source for a boot loader. It may extend this list of entries with 362additional items from other configuration files (for example its own native 363configuration files) or automatically detected other entries without explicit 364configuration. 365 366To make this explicitly clear: this specification is designed with "free" 367operating systems in mind, starting Windows or macOS is out of focus with these 368configuration snippets, use boot-loader specific solutions for that. In the 369text above, if we say "OS" we hence imply "free", i.e. primarily Linux (though 370this could be easily be extended to the BSDs and whatnot). 371 372Note that all paths used in the configuration snippets use a Unix-style "/" as 373path separator. This needs to be converted to an EFI-style "\\" separator in 374EFI boot loaders. 375 376 377## Logic 378 379A _boot loader_ needs a file system driver to discover and read `$BOOT`, then 380simply reads all files `$BOOT/loader/entries/*.conf`, and populates its boot 381menu with this. On EFI, it then extends this with any unified kernel images 382found in `$BOOT/EFI/Linux/*.efi`. It may also add additional entries, for 383example a "Reboot into firmware" option. Optionally it may sort the menu based 384on the `sort-key`, `machine-id` and `version` fields, and possibly others. It 385uses the file name to identify specific items, for example in case it supports 386storing away default entry information somewhere. A boot loader should 387generally not modify these files. 388 389For "Boot Loader Specification Entries" (Type #1), the _kernel package 390installer_ installs the kernel and initrd images to `$BOOT` (it is recommended 391to place these files in a vendor and OS and installation specific directory) 392and then generates a configuration snippet for it, placing this in 393`$BOOT/loader/entries/xyz.conf`, with xyz as concatenation of machine id and 394version information (see above). The files created by a kernel package are 395private property of the kernel package and should be removed along with it. 396 397For "EFI Unified Kernel Images" (Type #2), the vendor or kernel package 398installer creates the combined image and drops it into `$BOOT/EFI/Linux/`. This 399file is also private property of the kernel package and should be removed along 400with it. 401 402A _UI application_ intended to show available boot options shall operate 403similar to a boot loader, but might apply additional filters, for example by 404filtering out the booted OS via the machine ID, or by suppressing all but the 405newest kernel versions. 406 407An _OS installer_ picks the right place for `$BOOT` as defined above (possibly 408creating a partition and file system for it) and pre-creates the 409`/loader/entries/` directory in it. It then installs an appropriate boot loader 410that can read these snippets. Finally, it installs one or more kernel packages. 411 412 413## Out of Focus 414 415There are a couple of items that are out of focus for this specification: 416 417* If userspace can figure out the available boot options, then this is only 418 useful so much: we'd still need to come up with a way how userspace could 419 communicate to the boot loader the default boot loader entry temporarily or 420 persistently. Defining a common scheme for this is certainly a good idea, but 421 out of focus for this specification. 422* This specification is just about "Free" Operating systems. Hooking in other 423 operating systems (like Windows and macOS) into the boot menu is a different 424 story and should probably happen outside of this specification. For example, 425 boot loaders might choose to detect other available OSes dynamically at 426 runtime without explicit configuration (like `systemd-boot` does it), or via 427 native configuration (for example via explicit Grub2 configuration generated 428 once at installation). 429* This specification leaves undefined what to do about systems which are 430 upgraded from an OS that does not implement this specification. As the 431 previous boot loader logic was largely handled by in distribution-specific 432 ways we probably should leave the upgrade path (and whether there actually is 433 one) to the distributions. The simplest solution might be to simply continue 434 with the old scheme for old installations and use this new scheme only for 435 new installations. 436 437 438## Links 439 440[GUID Partition Table](https://en.wikipedia.org/wiki/GUID_Partition_Table)<br> 441[Boot Loader Interface](BOOT_LOADER_INTERFACE.md)<br> 442[Discoverable Partitions Specification](DISCOVERABLE_PARTITIONS.md)<br> 443[`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br> 444[`bootctl(1)`](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br> 445[`systemd-gpt-auto-generator(8)`](https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html) 446