1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6 cfg = config.boot.loader.systemd-boot;
7
8 efi = config.boot.loader.efi;
9
10 gummibootBuilder = pkgs.substituteAll {
11 src = ./systemd-boot-builder.py;
12
13 isExecutable = true;
14
15 inherit (pkgs) python3;
16
17 systemd = config.systemd.package;
18
19 nix = config.nix.package.out;
20
21 timeout = if config.boot.loader.timeout != null then config.boot.loader.timeout else "";
22
23 editor = if cfg.editor then "True" else "False";
24
25 inherit (cfg) consoleMode;
26
27 inherit (efi) efiSysMountPoint canTouchEfiVariables;
28 };
29in {
30
31 imports =
32 [ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ])
33 ];
34
35 options.boot.loader.systemd-boot = {
36 enable = mkOption {
37 default = false;
38
39 type = types.bool;
40
41 description = "Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager";
42 };
43
44 editor = mkOption {
45 default = true;
46
47 type = types.bool;
48
49 description = ''
50 Whether to allow editing the kernel command-line before
51 boot. It is recommended to set this to false, as it allows
52 gaining root access by passing init=/bin/sh as a kernel
53 parameter. However, it is enabled by default for backwards
54 compatibility.
55 '';
56 };
57
58 consoleMode = mkOption {
59 default = "keep";
60
61 type = types.enum [ "0" "1" "2" "auto" "max" "keep" ];
62
63 description = ''
64 The resolution of the console. The following values are valid:
65 </para>
66 <para>
67 <itemizedlist>
68 <listitem><para>
69 <literal>"0"</literal>: Standard UEFI 80x25 mode
70 </para></listitem>
71 <listitem><para>
72 <literal>"1"</literal>: 80x50 mode, not supported by all devices
73 </para></listitem>
74 <listitem><para>
75 <literal>"2"</literal>: The first non-standard mode provided by the device firmware, if any
76 </para></listitem>
77 <listitem><para>
78 <literal>"auto"</literal>: Pick a suitable mode automatically using heuristics
79 </para></listitem>
80 <listitem><para>
81 <literal>"max"</literal>: Pick the highest-numbered available mode
82 </para></listitem>
83 <listitem><para>
84 <literal>"keep"</literal>: Keep the mode selected by firmware (the default)
85 </para></listitem>
86 </itemizedlist>
87 '';
88 };
89 };
90
91 config = mkIf cfg.enable {
92 assertions = [
93 {
94 assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
95
96 message = "This kernel does not support the EFI boot stub";
97 }
98 ];
99
100 boot.loader.grub.enable = mkDefault false;
101
102 boot.loader.supportsInitrdSecrets = true;
103
104 system = {
105 build.installBootLoader = gummibootBuilder;
106
107 boot.loader.id = "systemd-boot";
108
109 requiredKernelConfig = with config.lib.kernelConfig; [
110 (isYes "EFI_STUB")
111 ];
112 };
113 };
114}