]> git.ipfire.org Git - thirdparty/systemd.git/blob - docs/BOOT_LOADER_SPECIFICATION.md
Merge pull request #24620 from poettering/measure-tweaks
[thirdparty/systemd.git] / docs / BOOT_LOADER_SPECIFICATION.md
1 ---
2 title: Boot Loader Specification
3 category: Booting
4 layout: default
5 SPDX-License-Identifier: LGPL-2.1-or-later
6 ---
7
8 # The Boot Loader Specification
9
10 This document defines a set of file formats and naming conventions that allow
11 the boot loader menu entries to be shared between multiple operating systems
12 and boot loaders installed on one device.
13
14 Operating systems cooperatively manage boot loader menu entry directories that
15 contain drop-in files, making multi-boot scenarios easy to support. Boot menu
16 entries are defined via two simple formats that can be understood by different
17 boot loader implementations, operating systems, and userspace programs. The
18 same scheme can be used to prepare OS media for cases where the firmware
19 includes a boot loader.
20
21 ## Target Audience
22
23 The target audience for this specification is:
24
25 * Boot loader developers, to write a boot loader that directly reads its
26 menu entries from these files
27 * Firmware developers, to add generic boot loading support directly to the
28 firmware itself
29 * OS installer developers, to create appropriate partitions and set up the
30 initial boot loader menu entries
31 * Distribution developers, to create appropriate menu entry snippets when
32 installing or updating kernel packages
33 * UI developers, to implement user interfaces that list and select among the
34 available boot options
35
36 ## The Partitions
37
38 Everything described below is located on one or two partitions. The boot loader
39 or user-space programs reading the boot loader menu entries should locate them
40 in the following manner:
41
42 * On disks with an MBR partition table:
43
44 * The boot partition — a partition with the type ID of `0xEA` — shall be used
45 as the single location for boot loader menu entries.
46
47 * On disks with GPT (GUID Partition Table)
48
49 * The EFI System Partition (ESP for short) — a partition with a GPT type GUID
50 of `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` — may be used as one of two locations for
51 boot loader menu entries.
52
53 * Optionally, an Extended Boot Loader Partition (XBOOTLDR partition for
54 short) — a partition with GPT type GUID of
55 `bc13c2ff-59e6-4262-a352-b275fd6f7172` — may be used as the second of two
56 locations for boot loader menu entries. This partition must be located on
57 the same disk as the ESP.
58
59 There may be at most one partition of each of the types listed above on the
60 same disk.
61
62 **Note:** _These partitions are **shared** among all OS installations on the
63 same disk. Instead of maintaining one boot partition per installed OS (as
64 `/boot/` was traditionally handled), all installed OSes use the same place for
65 boot loader menu entries._
66
67 For systems where the firmware is able to read file systems directly, the ESP
68 must — and the MBR boot and GPT XBOOTLDR partition should — be a file system
69 readable by the firmware. For most systems this means VFAT (16 or 32
70 bit). Applications accessing both partitions should hence not assume that
71 fancier file system features such as symlinks, hardlinks, access control or
72 case sensitivity are supported.
73
74 ### The `$BOOT` Partition Placeholder
75
76 In the text below, the placeholder `$BOOT` will be used to refer to the
77 partition determined as follows:
78
79 1. On disks with an MBR partition table: → the boot partition, as described above
80
81 2. On disks with a GPT partition table: → the XBOOTLDR partition if it exists
82
83 3. Otherwise, on disks with a GPT partition table: → the ESP
84
85 `$BOOT` is the *primary* place to put boot menu entry resources into, but
86 typically not the only one. Most importantly, boot loaders should also pick up
87 menu entries from the ESP, even if XBOOTLDR exists (for details see below).
88
89 ### Creating These Partitions
90
91 An installer for an operating system should use this logic when selecting or
92 creating partitions:
93
94 * If a boot partition (in case of MBR) or an XBOOTLDR partition (in case of
95 GPT) already exists it should be used as `$BOOT` and used as primary
96 location to place boot loader menu resources in.
97
98 * Otherwise, if on GPT and an ESP is found and it is large enough (let's say
99 at least 1G) it should be used as `$BOOT` and used as primary location to
100 place boot loader menu resources in.
101
102 * Otherwise, if on GPT and neither XBOOTLDR nor ESP exist, an ESP should be
103 created of the appropriate size and be used as `$BOOT`, and used as primary
104 location to place boot loader menu resources in.
105
106 * Otherwise, a boot partition (in case of MBR) or XBOOTLDR partition (in case
107 of GPT) should be created of an appropriate size, and be used as `$BOOT`,
108 and used as primary location to place boot loader menu resources in.
109
110 These partitions shall be determined during _installation time_, and
111 `/etc/fstab` entries may be created.
112
113 ### Mount Points
114
115 It is recommended to mount `$BOOT` to `/boot/`, and the ESP to `/efi/`. If
116 `$BOOT` and the ESP are the same, then either a bind mount or a symlink should
117 be established making the partition available under both paths.
118
119 (Mounting the ESP to `/boot/efi/`, as was traditionally done, is not
120 recommended. Such a nested setup complicates an implementation via direct
121 `autofs` mounts — as implemented by `systemd` for example —, as establishing
122 the inner `autofs` will trigger the outer one. Mounting the two partitions via
123 `autofs` is recommended because the simple VFAT file system has weak data
124 integrity properties and should remain unmounted whenever possible.)
125
126 ## Boot Loader Entries
127
128 This specification defines two types of boot loader entries. The first type is
129 text based, very simple, and suitable for a variety of firmware, architecture
130 and image types ("Type #1"). The second type is specific to EFI, but allows
131 single-file images that embed all metadata in the kernel binary itself, which
132 is useful to cryptographically sign them as one file for the purpose of
133 SecureBoot ("Type #2").
134
135 Not all boot loader entries will apply to all systems. For example, Type #1
136 entries that use the `efi` key and all Type #2 entries only apply to EFI
137 systems. Entries using the `architecture` key might specify an architecture that
138 doesn't match the local one. Boot loaders should ignore all entries that don't
139 match the local platform and what the boot loader can support, and hide them
140 from the user. Only entries matching the feature set of boot loader and system
141 shall be considered and displayed. This allows image builders to put together
142 images that transparently support multiple different architectures.
143
144 Note that the three partitions described above are not supposed to be the
145 exclusive territory of this specification. This specification only defines
146 semantics of the `/loader/entries/` directory (along with the companion file
147 `/loader/entries.srel`) and the `/EFI/Linux/` directory inside the file system,
148 but it doesn't intend to define contents of the rest of the file system. Boot
149 loaders, firmware, and other software implementing this specification may
150 choose to place other files and directories in the same file system. For
151 example, boot loaders that implement this specification might install their own
152 boot code on the same partition; this is particularly common in the case of the
153 ESP. Implementations of this specification must be able to operate correctly if
154 files or directories other than `/loader/entries/` and `/EFI/Linux/` are found
155 in the top level directory. Implementations that add their own files or
156 directories to the file systems should use well-named directories, to make name
157 collisions between multiple users of the file system unlikely.
158
159 ### Type #1 Boot Loader Specification Entries
160
161 `/loader/entries/` in `$BOOT` is the primary directory containing Type #1
162 drop-in snippets defining boot entries, one `.conf` file for each boot menu
163 item. Each OS may provide one or more such entries.
164
165 If the ESP is separate from `$BOOT` it may also contain a `/loader/entries/`
166 directory, where the boot loader should look for boot entry snippets, as an
167 additional source. The boot loader should enumerate both directories and
168 present a merged list to the user. Note that this is done for compatibility
169 only: while boot loaders should look in both places, OSes should only add their
170 files to `$BOOT`.
171
172 **Note:** _In all cases the `/loader/entries/` directory should be located
173 directly in the root of the file system. Specifically, the `/loader/entries/`
174 directory should **not** be located under the `/EFI/` subdirectory on the ESP._
175
176 The file name of the boot entry snippets is used for identification of the boot
177 item but shall never be presented to the user in the UI. The file name may be
178 chosen freely but should be unique enough to avoid clashes between OS
179 installations. More specifically, it is suggested to include the `entry-token`
180 (see
181 [kernel-install](https://www.freedesktop.org/software/systemd/man/kernel-install.html))
182 or machine ID (see
183 [/etc/machine-id](https://www.freedesktop.org/software/systemd/man/machine-id.html)),
184 and the kernel version (as returned by `uname -r`, including the OS
185 identifier), so that the whole filename is
186 `$BOOT/loader/entries/<entry-token-or-machine-id>-<version>.conf`.
187
188 Example: `$BOOT/loader/entries/6a9857a393724b7a981ebb5b8495b9ea-3.8.0-2.fc19.x86_64.conf`.
189
190 In order to maximize compatibility with file system implementations and
191 restricted boot loader environments, and to minimize conflicting character use
192 with other programs, file names shall be chosen from a restricted character
193 set: ASCII upper and lower case characters, digits, "+", "-", "_" and ".".
194 Also, the file names should have a length of at least one and at most 255
195 characters (including the file name suffix).
196
197 These boot loader menu snippets shall be UNIX-style text files (i.e. lines
198 separated by a single newline character), in the UTF-8 encoding. The
199 boot loader menu snippets are loosely inspired by Grub1's configuration syntax.
200 Lines beginning with "#" are used for comments and shall be ignored. The first
201 word of a line is used as key and is separated by one or more spaces from the
202 value.
203
204 #### Type #1 Boot Loader Entry Keys
205
206 The following keys are recognized:
207
208 * `title` is a human-readable title for this menu item to be displayed in the
209 boot menu. It is a good idea to initialize this from the `PRETTY_NAME=` of
210 [os-release](https://www.freedesktop.org/software/systemd/man/os-release.html).
211 This name should be descriptive and does not have to be unique. If a boot
212 loader discovers two entries with the same title it should show more than
213 just the raw title in the UI, for example by appending the `version`
214 field. This field is optional.
215
216 Example: `title Fedora 18 (Spherical Cow)`
217
218 * `version` is a human-readable version for this menu item. This is usually the
219 kernel version and is intended for use by OSes to install multiple kernel
220 versions with the same `title` field. This field is used for sorting entries,
221 so that the boot loader can order entries by age or select the newest one
222 automatically. This field is optional.
223
224 See [Sorting](#sorting) below.
225
226 Example: `version 3.7.2-201.fc18.x86_64`
227
228 * `machine-id` is the machine ID of the OS. This can be used by boot loaders
229 and applications to filter out boot entries, for example to show only a
230 single newest kernel per OS, to group items by OS, or to filter out the
231 currently booted OS when showing only other installed operating systems.
232 This ID shall be formatted as 32 lower case hexadecimal characters
233 (i.e. without any UUID formatting). This key is optional.
234
235 Example: `machine-id 4098b3f648d74c13b1f04ccfba7798e8`
236
237 * `sort-key` is a short string used for sorting entries on display. This should
238 typically be initialized from the `IMAGE_ID=` or `ID=` fields of
239 [os-release](https://www.freedesktop.org/software/systemd/man/os-release.html),
240 possibly with an additional suffix. This field is optional.
241
242 Example: `sort-key fedora`
243
244 * `linux` is the Linux kernel image to execute and takes a path relative to the
245 root of the file system containing the boot entry snippet itself. It is
246 recommended that every distribution creates an entry-token/machine-id and
247 version specific subdirectory and places its kernels and initrd images there
248 (see below).
249
250 Example: `linux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux`
251
252 * `initrd` is the initrd `cpio` image to use when executing the kernel. This key
253 may appear more than once in which case all specified images are used, in the
254 order they are listed.
255
256 Example: `initrd 6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd`
257
258 * `efi` refers to an arbitrary EFI program. If this key is set, and the system
259 is not an EFI system, this entry should be hidden.
260
261 * `options` shall contain kernel parameters to pass to the Linux kernel to
262 spawn. This key is optional and may appear more than once in which case all
263 specified parameters are combined in the order they are listed.
264
265 Example: `options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 quiet`
266
267 * `devicetree` refers to the binary device tree to use when executing the
268 kernel. This key is optional.
269
270 Example: `devicetree 6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.armv7hl/tegra20-paz00.dtb`
271
272 * `devicetree-overlay` refers to a list of device tree overlays that should be
273 applied by the boot loader. Multiple overlays are separated by spaces and
274 applied in the same order as they are listed. This key is optional but
275 depends on the `devicetree` key.
276
277 Example: `devicetree-overlay /6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_A.dtbo /6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_B.dtbo`
278
279 * `architecture` refers to the architecture this entry is for. The argument
280 should be an architecture identifier, using the architecture vocabulary
281 defined by the EFI specification (i.e. `IA32`, `x64`, `IA64`, `ARM`, `AA64`,
282 …). If specified and it does not match the local system architecture this
283 entry should be hidden. The comparison should be done case-insensitively.
284
285 Example: `architecture aa64`
286
287 Each boot loader menu entry drop-in snippet must include at least a `linux` or an `efi`
288 key. Here is an example for a complete drop-in file:
289
290 # /boot/loader/entries/6a9857a393724b7a981ebb5b8495b9ea-3.8.0-2.fc19.x86_64.conf
291 title Fedora 19 (Rawhide)
292 sort-key fedora
293 machine-id 6a9857a393724b7a981ebb5b8495b9ea
294 version 3.8.0-2.fc19.x86_64
295 options root=UUID=6d3376e4-fc93-4509-95ec-a21d68011da2 quiet
296 architecture x64
297 linux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux
298 initrd /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd
299
300 On EFI systems all Linux kernel images should be EFI images. In order to
301 increase compatibility with EFI systems it is highly recommended only to
302 install EFI kernel images, even on non-EFI systems, if that's applicable and
303 supported on the specific architecture.
304
305 Conversely, in order to increase compatibility it is recommended to install
306 generic kernel images that make few assumptions about the firmware they run on,
307 i.e. it is a good idea that both images shipped as UEFI PE images and those
308 which are not don't make unnecessary assumption on the underlying firmware,
309 i.e. don't hard depend on legacy BIOS calls or UEFI boot services.
310
311 When Type #1 boot loader menu entry snippets refer to other files (for `linux`,
312 `initrd`, `efi`, `devicetree`, and `devicetree-overlay`), those files must be
313 located on the same partition, and the paths must be absolute paths relative to
314 the root of that file system. The naming of those files can be chosen by the
315 installer. A recommended scheme is described in the next section. Paths should
316 be normalized, i.e. not include `..`, `.` or a sequence of more than one
317 `/`. Paths may be prefixed with a `/`, but this is optional and has the same
318 effect as paths without it: all paths are always relative to the root directory
319 of the partition they are referenced from.
320
321 Even though the backing file system is typically case-insensitive (i.e. VFAT)
322 it is strongly recommended to reference files in the casing actually used for
323 the directories/files, so that placing these files on other file systems is
324 still safe and robust.
325
326 ### Recommended Directory Layout for Additional Files
327
328 It is recommended to place the kernel and other other files comprising a single
329 boot loader entry in a separate directory:
330 `/<entry-token-or-machine-id>/<version>/`. This naming scheme uses the same
331 elements as the boot loader menu entry snippet, providing the same level of
332 uniqueness.
333
334 Example: `$BOOT/6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux`
335 `$BOOT/6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd`
336
337 Other naming schemes are possible. In particular, traditionally a flat naming
338 scheme with files in the root directory was used. This is not recommended
339 because it is hard to avoid conflicts in a multi-boot installation.
340
341 ### Standard-conformance Marker File
342
343 Unfortunately, there are implementations of boot loading infrastructure that
344 are also using the `/loader/entries/` directory, but install files that do not
345 follow this specification. In order to minimize confusion, a boot loader
346 implementation may place the file `/loader/entries.srel` next to the
347 `/loader/entries/` directory containing the ASCII string `type1` (followed by a
348 UNIX newline). Tools that need to determine whether an existing directory
349 implements the semantics described here may check for this file and contents:
350 if it exists and contains the mentioned string, it shall assume a
351 standards-compliant implementation is in place. If it exists but contains a
352 different string it shall assume other semantics are implemented. If the file
353 does not exist, no assumptions should be made.
354
355 ### Type #2 EFI Unified Kernel Images
356
357 A unified kernel image is a single EFI PE executable combining an EFI stub
358 loader, a kernel image, an initrd image, and the kernel command line. See
359 [systemd-stub(7)](https://www.freedesktop.org/software/systemd/man/systemd-stub.html)
360 for details. The primary place for such unified images is the `/EFI/Linux/`
361 directory in `$BOOT`. Operating systems should place unified EFI kernels only
362 in the `$BOOT` partition. Boot loaders should also look in the `/EFI/Linux/` of
363 the ESP — if it is different from `$BOOT` — and present a merged list of menu
364 entries from both partitions. Regardless if placed in the primary or secondary
365 location: the files must have the extension `.efi`. Support for images of this
366 type is of course specific to systems with EFI firmware. Ignore this section if
367 you work on systems not supporting EFI.
368
369 Type #2 file names should be chosen from the same restricted character set as
370 Type #1 described above (but with the file name suffix of `.efi` instead of
371 `.conf`).
372
373 Images of this type have the advantage that all metadata and payload that makes
374 up the boot entry is contained in a single PE file that can be signed
375 cryptographically as one for the purpose of EFI SecureBoot.
376
377 A valid unified kernel image in the `/EFI/Linux/` directory must contain two PE sections:
378
379 * `.cmdline` section with the kernel command line,
380 * `.osrel` section with an embedded copy of the
381 [os-release](https://www.freedesktop.org/software/systemd/man/os-release.html)
382 file describing the image.
383
384 The `PRETTY_NAME=` and `VERSION_ID=` fields in the embedded `os-release` file
385 are used the same as `title` and `version` in the Type #1 entries. The
386 `.cmdline` section is used instead of the `options` field. `linux` and `initrd`
387 fields are not necessary, and there is no counterpart for the `machine-id`
388 field.
389
390 On EFI, any such images shall be added to the list of valid boot entries.
391
392 ### Additional Notes
393
394 Note that these boot entry snippets and unified kernels do not need to be the
395 only menu entry sources for a boot loader. It may extend this list of
396 entries with additional items from other configuration files (for example its
397 own native configuration files) or automatically detected other entries without
398 explicit configuration.
399
400 To make this explicitly clear: this specification is designed with "free"
401 operating systems in mind, starting Windows or MacOS is out of focus with these
402 boot loader menu entry snippets, use boot-loader specific solutions for
403 that. In the text above, if we say "OS" we hence imply "free", i.e. primarily
404 Linux (though this could be easily be extended to the BSDs and whatnot).
405
406 Note that all paths used in the boot loader menu entry snippets use a
407 Unix-style "/" as path separator. This needs to be converted to an EFI-style
408 "\\" separator in EFI boot loaders.
409
410
411 ## Locating Boot Entries
412
413 A _boot loader_ locates the XBOOTLDR partition and the ESP, then simply reads
414 all the files `/loader/entries/*.conf` in them, and populates its boot menu
415 (and handle gracefully if one of the two partitions is missing). On EFI, it
416 then extends this with any unified kernel images found in `/EFI/Linux/*.efi` in
417 the two partitions. It may also add additional entries, for example a "Reboot
418 into firmware" option. Optionally it may sort the menu based on the
419 `sort-key`, `machine-id` and `version` fields, and possibly others. It uses the
420 file name to identify specific items, for example in case it supports storing
421 away default entry information somewhere. A boot loader should generally not
422 modify these files.
423
424 For "Boot Loader Specification Entries" (Type #1), the _kernel package
425 installer_ installs the kernel and initrd images to `$BOOT`. It is recommended
426 to place these files in a vendor and OS and installation specific directory. It
427 then generates a boot loader menu entry snippet, placing it in
428 `$BOOT/loader/entries/xyz.conf`, with "xyz" as concatenation of
429 entry-token/machine-id and version information (see above). The files created
430 by a kernel package are tied to the kernel package and should be removed along
431 with it.
432
433 For "EFI Unified Kernel Images" (Type #2), the vendor or kernel package
434 installer should create the combined image and drop it into
435 `$BOOT/EFI/Linux/`. This file is also tied to the kernel package and should be
436 removed along with it.
437
438 A _UI application_ intended to show available boot options shall operate
439 similarly to a boot loader (and thus search both `$BOOT` and the ESP if
440 distinct), but might apply additional filters, for example by filtering the
441 booted OS via the machine ID, or by suppressing all but the newest kernel
442 versions.
443
444 An _OS installer_ picks the right place for `$BOOT` as defined above (possibly
445 creating a partition and file system for it) and creates the `/loader/entries/`
446 directory and the `/loader/entries.srel` file in it (the latter only if the
447 directory didn't exist yet). It then installs an appropriate boot loader that
448 can read these snippets. Finally, it installs one or more kernel packages.
449
450 ## Boot counting
451
452 The main idea is that when boot entries are initially installed, they are
453 marked as "indeterminate" and assigned a number of boot attempts. Each time the
454 boot loader tries to boot an entry, it decreases this count by one. If the
455 operating system considers the boot as successful, it removes the counter
456 altogether and the entry becomes "good". Otherwise, once the assigned number of
457 boots is exhausted, the entry is marked as "bad".
458
459 Which boots are "successful" is determined by the operating system. systemd
460 provides a generic mechanism that can be extended with arbitrary checks and
461 actions, see [Automatic Boot Assessment](AUTOMATIC_BOOT_ASSESSMENT.md), but the
462 boot counting mechanism described in this specification can also be used with
463 other implementations.
464
465 The boot counting data is stored in the name of the boot loader entry. A boot
466 loader entry file name may contain a plus (`+`) followed by a number. This may
467 optionally be followed by a minus (`-`) followed by a second number. The dot
468 (`.`) and file name suffix (`conf` of `efi`) must immediately follow. Boot
469 counting is enabled for entries which match this pattern.
470
471 The first number is the "tries left" counter signifying how many attempts to boot
472 this entry shall still be made. The second number is the "tries done" counter,
473 showing how many failed attempts to boot it have already been made. Each time
474 a boot loader entry marked this way is booted, the first counter is decremented,
475 and the second one incremented. (If the second counter is missing,
476 then it is assumed to be equivalent to zero.) If the "tries left" counter is
477 above zero the entry is still considered "indeterminate". A boot entry with the
478 "tries left" counter at zero is considered "bad".
479
480 If the boot attempt completed successfully the entry's counters are removed
481 from the name (entry state becomes "good"), thus turning off boot counting for
482 this entry.
483
484 ## Sorting
485
486 The boot loader menu should generally show entries in some order meaningful to
487 the user. The `title` key is free-form and not suitable to be used as the
488 primary sorting key. Instead, the boot loader should use the following rules:
489
490 1. Entries which are subject to boot counting and are marked as "bad", should
491 be sorted later than all other entries. Entries which are marked as
492 "indeterminate" or "good" (or were not subject to boot counting at all),
493 are thus sorted earlier.
494
495 2. If `sort-key` is set on both entries, use in order of priority,
496 the `sort-key` (A-Z, increasing [alphanumerical order](#alphanumerical-order)),
497 `machine-id` (A-Z, increasing alphanumerical order),
498 and `version` keys (decreasing [version order](#version-order)).
499
500 3. If `sort-key` is set on one entry, it sorts earlier.
501
502 4. At the end, if necessary, when `sort-key` is not set or those fields are not
503 set or are all equal, the boot loader should sort using the file name of the
504 entry (decreasing version sort), with the suffix removed.
505
506 **Note:** _This description assumes that the boot loader shows entries in a
507 traditional menu, with newest and "best" entries at the top, thus entries with
508 a higher version number are sorter *earlier*. The boot loader is free to
509 use a different direction (or none at all) during display._
510
511 **Note:** _The boot loader should allow booting "bad" entries, e.g. in case no
512 other entries are left or they are unusable for other reasons. It may
513 deemphasize or hide such entries by default._
514
515 **Note:** _"Bad" boot entries have a suffix of "+0-`n`", where `n` is the
516 number of failed boot attempts. Removal of the suffix is not necessary for
517 comparisons described by the last point above. In the unlikely scenario that we
518 have multiple such boot entries that differ only by the boot counting data, we
519 would sort them by `n`._
520
521 ### Alphanumerical Order
522
523 Free-form strings and machine IDs should be compared using a method equivalent
524 to [strcmp(3)](https://man7.org/linux/man-pages/man3/strcmp.3.html) on their
525 UTF-8 representations. If just one of the strings is unspecified or empty, it
526 compares lower. If both strings are unspecified or empty, they compare equal.
527
528 ### Version Order
529
530 The following method should be used to compare version strings. The algorithm
531 is based on rpm's `rpmvercmp()`, but not identical.
532
533 ASCII letters (`a-z`, `A-Z`) and digits (`0-9`) form alphanumerical components of the version.
534 Minus (`-`) separates the version and release parts.
535 Dot (`.`) separates parts of version or release.
536 Tilde (`~`) is a prefix that always compares lower.
537 Caret (`^`) is a prefix that always compares higher.
538
539 Both strings are compared from the beginning until the end, or until the
540 strings are found to compare as different. In a loop:
541 1. Any characters which are outside of the set of listed above (`a-z`, `A-Z`, `0-9`, `-`, `.`, `~`, `^`)
542 are skipped in both strings. In particular, this means that non-ASCII characters
543 that are Unicode digits or letters are skipped too.
544 2. If one of the strings has ended: if the other string hasn't, the string that
545 has remaining characters compares higher. Otherwise, the strings compare
546 equal.
547 3. If the remaining part of one of strings starts with `~`:
548 if other remaining part does not start with `~`,
549 the string with `~` compares lower. Otherwise, both tilde characters are skipped.
550 4. The check from point 2. is repeated here.
551 5. If the remaining part of one of strings starts with `-`:
552 if the other remaining part does not start with `-`,
553 the string with `-` compares lower. Otherwise, both minus characters are skipped.
554 6. If the remaining part of one of strings starts with `^`:
555 if the other remaining part does not start with `^`,
556 the string with `^` compares higher. Otherwise, both caret characters are skipped.
557 6. If the remaining part of one of strings starts with `.`:
558 if the other remaining part does not start with `.`,
559 the string with `.` compares lower. Otherwise, both dot characters are skipped.
560 7. If either of the remaining parts starts with a digit, numerical prefixes are
561 compared numerically. Any leading zeroes are skipped.
562 The numerical prefixes (until the first non-digit character) are evaluated as numbers.
563 If one of the prefixes is empty, it evaluates as 0.
564 If the numbers are different, the string with the bigger number compares higher.
565 Otherwise, the comparison continues at the following characters at point 1.
566 8. Leading alphabetical prefixes are compared alphabetically.
567 The substrings are compared letter-by-letter.
568 If both letters are the same, the comparison continues with the next letter.
569 Capital letters compare lower than lower-case letters (`A < a`).
570 When the end of one substring has been reached (a non-letter character or the end
571 of the whole string), if the other substring has remaining letters, it compares higher.
572 Otherwise, the comparison continues at the following characters at point 1.
573
574 Examples (with '' meaning the empty string):
575
576 * `11 == 11`
577 * `systemd-123 == systemd-123`
578 * `bar-123 < foo-123`
579 * `123a > 123`
580 * `123.a > 123`
581 * `123.a < 123.b`
582 * `123a > 123.a`
583 * `11α == 11β`
584 * `A < a`
585 * '' < `0`
586 * `0.` > `0`
587 * `0.0` > `0`
588 * `0` < `~`
589 * '' < `~`
590
591 Note: [systemd-analyze](https://www.freedesktop.org/software/systemd/man/systemd-analyze.html)
592 implements this version comparison algorithm as
593 ```
594 systemd-analyze compare-versions <version-a> <version-b>
595 ```
596
597 ## Additional discussion
598
599 ### Why is there a need for this specification?
600
601 This specification brings the following advantages:
602
603 * Installation of new boot entries is more robust, as no explicit rewriting of
604 configuration files is required.
605
606 * It allows an out-of-the-box boot experience on any platform without the need
607 of traditional firmware mechanisms (e.g. BIOS calls, UEFI Boot Services).
608
609 * It improves dual-boot scenarios. Without cooperation, multiple Linux
610 installations tend to fight over which boot loader becomes the primary one in
611 possession of the MBR or the boot partition, and only that one installation
612 can then update the boot loader configuration. Other Linux installs have to
613 be manually configured to never touch the MBR and instead install a
614 chain-loaded boot loader in their own partition headers. In this new scheme
615 all installations share a loader directory and no manual configuration has to
616 take place. All participants implicitly cooperate due to removal of name
617 collisions and can install/remove their own boot menu entries without
618 interfering with the entries of other installed operating systems.
619
620 * Drop-in directories are now pretty ubiquitous on Linux as an easy way to
621 extend boot loader menus without having to edit, regenerate or manipulate
622 configuration files. For the sake of uniformity, we should do the same for
623 the boot menu.
624
625 * Userspace code can sanely parse boot loader menu entries which is essential
626 with modern firmware which does not necessarily initialize USB keyboards
627 during boot, which makes boot menus hard to reach for the user. If userspace
628 code can parse the boot loader menu entries too, UI can be written that
629 select a boot menu item to boot into before rebooting the machine, thus not
630 requiring interactivity during early boot.
631
632 * To unify and thus simplify menu entries of the various boot loaders, which
633 makes configuration of the boot loading process easier for users,
634 administrators, and developers alike.
635
636 * For boot loaders with configuration _scripts_ such as grub2, adopting this
637 spec allows for mostly static scripts that are generated only once at first
638 installation, but then do not need to be updated anymore as that is done via
639 drop-in files exclusively.
640
641 ### Why not simply rely on the EFI boot menu logic?
642
643 EFI is not ubiquitous, especially not in embedded systems. But even on systems
644 with EFI, which provides a boot options logic that can offer similar
645 functionality, this specification is still needed for the following reasons:
646
647 * The various EFI implementations implement the boot order/boot item logic to
648 different levels. Some firmware implementations do not offer a boot menu at
649 all and instead unconditionally follow the EFI boot order, booting the first
650 item that is working.
651
652 * If the firmware setup is used to reset data, usually all EFI boot entries
653 are lost, making the system entirely unbootable, as the firmware setups
654 generally do not offer a UI to define additional boot items. By placing the
655 menu item information on disk, it is always available, even if the firmware
656 configuration is lost.
657
658 * Harddisk images should be movable between machines and be bootable without
659 requiring firmware configuration. This also requires that the list
660 of boot options is defined on disk, and not in EFI variables alone.
661
662 * EFI is not universal yet (especially on non-x86 platforms), this
663 specification is useful both for EFI and non-EFI boot loaders.
664
665 * Many EFI systems disable USB support during early boot to optimize boot
666 times, thus making keyboard input unavailable in the EFI menu. It is thus
667 useful if the OS UI has a standardized way to discover available boot options
668 which can be booted to.
669
670 ### Why is the version comparison logic so complicated?
671
672 The `sort-key` allows us to group entries by "operating system", e.g. all
673 versions of Fedora together, no matter if they identify themselves as "Fedora
674 Workstation" or "Fedora Rawhide (prerelease)". The `sort-key` was introduced
675 only recently, so we need to provide a meaningful order for entries both with
676 and without it. Since it is a new concept, it is assumed that entries with
677 `sort-key` are newer.
678
679 In a traditional menu with entries displayed vertically, we want names to be
680 sorter alpabetically (CentOS, Debian, Fedora, OpenSUSE, …), it would be strange
681 to have them in reverse order. But when multiple kernels are available for the
682 same installation, we want to display the latest kernel with highest priority,
683 i.e. earlier in the list.
684
685 ### Why do you use file renames to store the counter? Why not a regular file?
686
687 Mainly two reasons: it's relatively likely that renames can be implemented
688 atomically even in simpler file systems, as renaming generally avoids
689 allocating or releasing data blocks. Writing to file contents has a much bigger
690 chance to be result in incomplete or corrupt data. Moreover renaming has the
691 benefit that the boot count metadata is directly attached to the boot loader
692 entry file, and thus the lifecycle of the metadata and the entry itself are
693 bound together. This means no additional clean-up needs to take place to drop
694 the boot loader counting information for an entry when it is removed.
695
696 ### Why not use EFI variables for storing the boot counter?
697
698 The memory chips used to back the persistent EFI variables are generally not of
699 the highest quality, hence shouldn't be written to more than necessary. This
700 means we can't really use it for changes made regularly during boot, but should
701 use it only for seldom-made configuration changes.
702
703 ### Out of Focus
704
705 There are a couple of items that are out of focus for this specification:
706
707 * If userspace can figure out the available boot options, then this is only
708 useful so much: we'd still need to come up with a way how userspace could
709 communicate to the boot loader the default boot loader entry temporarily or
710 persistently. Defining a common scheme for this is certainly a good idea, but
711 out of focus for this specification.
712
713 * This specification is just about "Free" Operating systems. Hooking in other
714 operating systems (like Windows and macOS) into the boot menu is a different
715 story and should probably happen outside of this specification. For example,
716 boot loaders might choose to detect other available OSes dynamically at
717 runtime without explicit configuration (like `systemd-boot` does it), or via
718 native configuration (for example via explicit Grub2 configuration generated
719 once at installation).
720
721 * This specification leaves undefined what to do about systems which are
722 upgraded from an OS that does not implement this specification. As the
723 previous boot loader logic was largely handled by in distribution-specific
724 ways we probably should leave the upgrade path (and whether there actually is
725 one) to the distributions. The simplest solution might be to simply continue
726 with the old scheme for old installations and use this new scheme only for
727 new installations.
728
729 * Referencing kernels or initrds on other partitions other than the partition
730 containing the Type #1 boot loader entry. This is by design, as specifying
731 other partitions or devices would require a non-trivial language for denoting
732 device paths. In particular this means that on non-EFI systems boot loader
733 menu entry snippets following this specification cannot be used to spawn
734 other operating systems (such as Windows).
735
736
737 ## Links
738
739 [GUID Partition Table](https://en.wikipedia.org/wiki/GUID_Partition_Table)<br>
740 [Boot Loader Interface](BOOT_LOADER_INTERFACE.md)<br>
741 [Discoverable Partitions Specification](DISCOVERABLE_PARTITIONS.md)<br>
742 [`systemd-boot(7)`](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br>
743 [`bootctl(1)`](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br>
744 [`systemd-gpt-auto-generator(8)`](https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html)