Skip to content

Commit a8ee254

Browse files
committed
0153-uefi-only: init
1 parent 553b132 commit a8ee254

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

rfcs/0153-uefi-only.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
feature: non_legacy_boot
3+
start-date: 2023-06-16
4+
author: Ryan Lahfa
5+
co-authors: (find a buddy later to help out with the RFC)
6+
shepherd-team: (names, to be nominated and accepted by RFC steering committee)
7+
shepherd-leader: (name to be appointed by RFC steering committee)
8+
related-issues: (will contain links to implementation PRs)
9+
---
10+
11+
# Summary
12+
[summary]: #summary
13+
14+
NixOS will have first-class support for UEFI
15+
and uses it as a default boot environment, for supported architectures,
16+
even in situations where only BIOS Boot Specification's legacy boot is available,
17+
via a dual-stage payload consisting of a polyfill bootloader/firmware and a standard
18+
UEFI bootloader.
19+
20+
To achieve this, it will downgrade the GRUB privileged position
21+
in the project and offer it as a "best effort" basis alternative bootloader.
22+
23+
# Motivation
24+
[motivation]: #motivation
25+
26+
Legacy boot is defined by the BIOS Boot specification, written in 1996: https://www.scs.stanford.edu/nyu/04fa/lab/specsbbs101.pdf.
27+
Nowadays, computers are defaulting to UEFI more and more for the extended features provided (e.g. SecureBoot, native network boot, etc.).
28+
29+
Nevertheless, many legacy boots machines or machines that does not have support for UEFI are used with NixOS: Single Board Computers for example
30+
on other architectures.
31+
32+
Let's put aside non-legacy boot payloads such as [Linuxboot](https://www.linuxboot.org/), [Ownerboot](https://sr.ht/~amjoseph/ownerboot/) and any similar payloads,
33+
those are not legacy and they definitely have their places in the project, though, at the time of writing, no such payload is offered in NixOS.
34+
35+
In nixpkgs, legacy boot forces a dichotomy between `boot.loader.efi` and... at least two legacy bootloaders **in tree**: GRUB and a family of UBoot/extlinux-compatible/etc.
36+
37+
In the case of GRUB, there are increasing problems with this bootloader:
38+
39+
- Upstream do not do releases anymore: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/tools/misc/grub/default.nix#L62-L350
40+
- Co-maintenance / release work with other ecosystems such as the kernel is simply not done: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/tools/misc/grub/default.nix#L345-L349 causing GRUB's drivers to explode in production for our users: https://github.com/NixOS/nixpkgs/pull/235222
41+
- Our own maintenance of GRUB is subpar: https://github.com/NixOS/nixpkgs/pull/227741 https://github.com/NixOS/nixpkgs/pull/226821 https://github.com/NixOS/nixpkgs/pull/195805 https://github.com/NixOS/nixpkgs/pull/95901 https://github.com/NixOS/nixpkgs/pull/236027
42+
- GRUB installation procedure uses `install-grub.pl`, one of the remaining Perl script: https://github.com/NixOS/nixpkgs/pull/95901#issuecomment-756702696 offered to rewrite it with sponsoring, but no one took the offer yet, it is also very complicated to integrate with it: https://github.com/nix-community/lanzaboote/pull/96
43+
- GRUB installation procedure for UEFI-only is still confusing because our scripts does not handle well UEFI-only (you have to pass `nodev` and this is not very well documented). See https://github.com/NixOS/nixpkgs/issues/222491
44+
45+
The worse about this, is this is our **default** bootloader for our install images **because** of legacy boot.
46+
47+
In the case of UBoot/extlinux-compatible/etc. : we should definitely keep it, polish it and improve it for a better support of embedded systems, e.g. merging the differences
48+
between Raspberry Pi's bootloader and extlinux-compatible's ones.
49+
50+
Getting rid of legacy boot opens up the way to get rid of GRUB as a default and offering an UEFI environment opens up the way to:
51+
52+
- having a default ISO booting systemd-boot which is a maintained (by systemd) bootloader with active releases, smaller code footprint, maintained also by Systemd team in Nixpkgs
53+
- Features like https://github.com/NixOS/nixpkgs/pull/84204 could also be enabled for legacy boot users
54+
- Users who wants to use GRUB drivers to mount non-standard ESP can make use of https://efi.akeo.ie/ which is compatible with any UEFI bootloader
55+
- Boot testing can split into 2 ways: legacy boot compatibility layer tests and UEFI boot tests
56+
- Successful adoption gives a positive signal to others distribution to consider it, provide development resources to improve it rather than being held by the existing things, etc.
57+
58+
# Detailed design
59+
[design]: #detailed-design
60+
61+
Currently, most x86 computers^[For a more complete reference, read: https://safeboot.dev/chain-of-trust/] boot in a similar way to this **on a very high level** :
62+
63+
```mermaid
64+
flowchart
65+
subgraph Firmware
66+
A((Power On)) --->|boots Intel Management Engine| M
67+
M((Intel Management Engine)) ---->|starts x86 CPU| C((x86 CPU))
68+
C -->|starts OEM payload: BIOS or UEFI| O((BIOS or UEFI))
69+
end
70+
subgraph Distribution
71+
O -->|boot further bootloaders| BL((GRUB or systemd-boot))
72+
BL -->|boot operating system| OS((NixOS))
73+
end
74+
```
75+
76+
In other platforms, you can see extra payloads like <https://github.com/ARM-software/arm-trusted-firmware> or <https://github.com/riscv-software-src/opensbi>
77+
before the distribution part, sometimes, it can be part of the distribution if control can be exerted.
78+
79+
Some machines does even have control on the OEM payload or a good subset of the firmware, for example, via <https://www.coreboot.org/> or
80+
<https://github.com/oreboot/oreboot>.
81+
82+
The idea is to transform this flowchart into:
83+
84+
```mermaid
85+
flowchart
86+
subgraph Firmware
87+
A((Power On)) --->|boots Intel Management Engine| M
88+
M((Intel Management Engine)) ---->|starts x86 CPU| C((x86 CPU))
89+
C -->|starts OEM payload: BIOS| O((BIOS))
90+
end
91+
subgraph Distribution
92+
O -->|boot UEFI environment| UB((U-Boot))
93+
UB -->|boot further bootloaders| BL((any UEFI-enabled bootloader))
94+
BL -->|boot operating system| OS((NixOS))
95+
end
96+
```
97+
98+
and keep it the old way whenever the OEM payload is UEFI already.
99+
100+
If we take a step back, we can notice this 2-stage payload boot story can be generalized in those situations:
101+
102+
```mermaid
103+
flowchart
104+
subgraph Firmware
105+
A((Power On)) --->|boots some evil chip| M
106+
M((Evil Chip 2000)) ---->|starts some architecture CPU| C(($arch CPU))
107+
end
108+
subgraph Distribution
109+
C -->|starts user-provided firmware| CBL((coreboot))
110+
CBL -->|starts user-provided payload| O((TianoCore, LinuxBoot, OwnerBoot, etc.))
111+
O -->|boot Linux operating system| OS((U-Boot))
112+
end
113+
```
114+
115+
In this situation, (c)oreboot could be a replacement of U-Boot environment and any UEFI-enabled bootloader could be replaced by any payload.
116+
117+
Therefore, the design has to be general enough to support both usecases.
118+
119+
Removing legacy boot will use a deprecation schedule and proceed into multiple steps. This RFC is dependent on accepted minimal implementations, where 'minimal' has to
120+
be defined in this RFC.
121+
122+
# Examples and Interactions
123+
[examples-and-interactions]: #examples-and-interactions
124+
125+
Fedora is considering doing this: https://lists.fedoraproject.org/archives/list/[email protected]/thread/GOETDM5SWINBX5ZDV37SWMHIPRRUVVTT/.
126+
127+
Asahi Linux is booting UEFI via UBoot without EFI variables and it has been great for them.
128+
129+
People who want to boot off strange partitions at boot-time can exploit UEFI drivers capability to load any filesystem driver and
130+
open the EFI System Partition in ZFS if they really insist.
131+
132+
# Drawbacks
133+
[drawbacks]: #drawbacks
134+
135+
- 2-stage boot for legacy BIOS systems is more than 1-stage boot
136+
- Increased internal complexity in the boot story of NixOS
137+
- Increased load and reliance on UBoot
138+
- The runtime service `SetVariable` will probably stay highly unstable for a while (variable storage)
139+
140+
# Alternatives
141+
[alternatives]: #alternatives
142+
143+
- Keeping legacy BIOS, doing nothing
144+
Then, we will continue to have users relying on bootloaders with shady maintenance stories and a skewed perception of what a bootloader can do (e.g. boot on a ZFS partition?).
145+
146+
- Keeping legacy BIOS, offering this new way as an option
147+
Then, we will continue to have users relying on bootloaders with shady maintenance stories and a skewed perception of what a bootloader can do (e.g. boot on a ZFS partition?).
148+
149+
- Keeping legacy BIOS, offering this new way as an option, deprecating legacy BIOS on a time schedule
150+
It is a minor variant of the proposal.
151+
152+
- Keeping legacy BIOS, switching only new users to this mechanism without any deprecation of legacy BIOS for the time being
153+
This turns the problem into maintenance in-tree of GRUB2, which is fine by me.
154+
155+
- Removing legacy BIOS, switching all users to this mechanism
156+
This does not have any deprecation schedule.
157+
158+
# Unresolved questions
159+
[unresolved]: #unresolved-questions
160+
161+
- How to migrate existing installs without any GPT partition table?
162+
- How to migrate existing installs with a GPT partition table but without a supported EFI System Partition, e.g. LVM
163+
- NTFS, XFS, exFAT, Amiga FFS/SFS, BFS, UFS, ZFS are handled via https://efi.akeo.ie/ which is an EFI driver that can be loaded
164+
- Subquestion: how to load EFI drivers for unsupported EFI System Partition?
165+
- Answer: Build EDK2 or UBoot with https://github.com/pbatard/efifs them.
166+
- When to do it?
167+
- What to do about variable storage (Asahi Linux showed this is not that important for a start)?
168+
- What to do about (>)dual boot configurations if variable storage is not available? (writing the EFI fallback directory will break the dual boot configuration.)
169+
- Design architecture in nixpkgs?
170+
171+
# Future work
172+
[future]: #future-work
173+
174+
- Improved support for UEFI features on non-UEFI native systems

0 commit comments

Comments
 (0)