···11111212## Submitting changes
13131414+Read the ["Submitting changes"](https://nixos.org/nixpkgs/manual/#chap-submitting-changes) section of the nixpkgs manual. It explains how to write, test, and iterate on your change, and which branch to base your pull request against.
1515+1616+Below is a short excerpt of some points in there:
1717+1418* Format the commit messages in the following way:
15191620 ```
···4044 * If there is no upstream license, `meta.license` should default to `lib.licenses.unfree`.
4145* `meta.maintainers` must be set.
42464343-See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes) and on how to [submit changes to nixpkgs](https://nixos.org/nixpkgs/manual/#chap-submitting-changes).
4747+See the nixpkgs manual for more details on [standard meta-attributes](https://nixos.org/nixpkgs/manual/#sec-standard-meta-attributes).
44484549## Writing good commit messages
4650
···4545options {kernel_params}
4646"""
47474848-# The boot loader entry for memtest86.
4949-#
5050-# TODO: This is hard-coded to use the 64-bit EFI app, but it could probably
5151-# be updated to use the 32-bit EFI app on 32-bit systems. The 32-bit EFI
5252-# app filename is BOOTIA32.efi.
5353-MEMTEST_BOOT_ENTRY = """title MemTest86
5454-efi /efi/memtest86/BOOTX64.efi
5555-"""
5656-5757-5848def generation_conf_filename(profile: Optional[str], generation: int, specialisation: Optional[str]) -> str:
5949 pieces = [
6050 "nixos",
···283273 except OSError as e:
284274 print("ignoring profile '{}' in the list of boot entries because of the following error:\n{}".format(profile, e), file=sys.stderr)
285275286286- memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
287287- if os.path.exists(memtest_entry_file):
288288- os.unlink(memtest_entry_file)
289289- shutil.rmtree("@efiSysMountPoint@/efi/memtest86", ignore_errors=True)
290290- if "@memtest86@" != "":
291291- mkdir_p("@efiSysMountPoint@/efi/memtest86")
292292- for path in glob.iglob("@memtest86@/*"):
293293- if os.path.isdir(path):
294294- shutil.copytree(path, os.path.join("@efiSysMountPoint@/efi/memtest86", os.path.basename(path)))
295295- else:
296296- shutil.copy(path, "@efiSysMountPoint@/efi/memtest86/")
276276+ for root, _, files in os.walk('@efiSysMountPoint@/efi/nixos/.extra-files', topdown=False):
277277+ relative_root = root.removeprefix("@efiSysMountPoint@/efi/nixos/.extra-files").removeprefix("/")
278278+ actual_root = os.path.join("@efiSysMountPoint@", relative_root)
279279+280280+ for file in files:
281281+ actual_file = os.path.join(actual_root, file)
282282+283283+ if os.path.exists(actual_file):
284284+ os.unlink(actual_file)
285285+ os.unlink(os.path.join(root, file))
286286+287287+ if not len(os.listdir(actual_root)):
288288+ os.rmdir(actual_root)
289289+ os.rmdir(root)
290290+291291+ mkdir_p("@efiSysMountPoint@/efi/nixos/.extra-files")
297292298298- memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
299299- memtest_entry_file_tmp_path = "%s.tmp" % memtest_entry_file
300300- with open(memtest_entry_file_tmp_path, 'w') as f:
301301- f.write(MEMTEST_BOOT_ENTRY)
302302- os.rename(memtest_entry_file_tmp_path, memtest_entry_file)
293293+ subprocess.check_call("@copyExtraFiles@")
303294304295 # Since fat32 provides little recovery facilities after a crash,
305296 # it can leave the system in an unbootable state, when a crash/outage
···2929 inherit (efi) efiSysMountPoint canTouchEfiVariables;
30303131 memtest86 = if cfg.memtest86.enable then pkgs.memtest86-efi else "";
3232+3333+ netbootxyz = if cfg.netbootxyz.enable then pkgs.netbootxyz-efi else "";
3434+3535+ copyExtraFiles = pkgs.writeShellScript "copy-extra-files" ''
3636+ empty_file=$(mktemp)
3737+3838+ ${concatStrings (mapAttrsToList (n: v: ''
3939+ ${pkgs.coreutils}/bin/install -Dp "${v}" "${efi.efiSysMountPoint}/"${escapeShellArg n}
4040+ ${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/"${escapeShellArg n}
4141+ '') cfg.extraFiles)}
4242+4343+ ${concatStrings (mapAttrsToList (n: v: ''
4444+ ${pkgs.coreutils}/bin/install -Dp "${pkgs.writeText n v}" "${efi.efiSysMountPoint}/loader/entries/"${escapeShellArg n}
4545+ ${pkgs.coreutils}/bin/install -D $empty_file "${efi.efiSysMountPoint}/efi/nixos/.extra-files/loader/entries/"${escapeShellArg n}
4646+ '') cfg.extraEntries)}
4747+ '';
3248 };
33493450 checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" {
···125141 <literal>true</literal>.
126142 '';
127143 };
144144+145145+ entryFilename = mkOption {
146146+ default = "memtest86.conf";
147147+ type = types.str;
148148+ description = ''
149149+ <literal>systemd-boot</literal> orders the menu entries by the config file names,
150150+ so if you want something to appear after all the NixOS entries,
151151+ it should start with <filename>o</filename> or onwards.
152152+ '';
153153+ };
154154+ };
155155+156156+ netbootxyz = {
157157+ enable = mkOption {
158158+ default = false;
159159+ type = types.bool;
160160+ description = ''
161161+ Make <literal>netboot.xyz</literal> available from the
162162+ <literal>systemd-boot</literal> menu. <literal>netboot.xyz</literal>
163163+ is a menu system that allows you to boot OS installers and
164164+ utilities over the network.
165165+ '';
166166+ };
167167+168168+ entryFilename = mkOption {
169169+ default = "o_netbootxyz.conf";
170170+ type = types.str;
171171+ description = ''
172172+ <literal>systemd-boot</literal> orders the menu entries by the config file names,
173173+ so if you want something to appear after all the NixOS entries,
174174+ it should start with <filename>o</filename> or onwards.
175175+ '';
176176+ };
177177+ };
178178+179179+ extraEntries = mkOption {
180180+ type = types.attrsOf types.lines;
181181+ default = {};
182182+ example = literalExpression ''
183183+ { "memtest86.conf" = '''
184184+ title MemTest86
185185+ efi /efi/memtest86/memtest86.efi
186186+ '''; }
187187+ '';
188188+ description = ''
189189+ Any additional entries you want added to the <literal>systemd-boot</literal> menu.
190190+ These entries will be copied to <filename>/boot/loader/entries</filename>.
191191+ Each attribute name denotes the destination file name,
192192+ and the corresponding attribute value is the contents of the entry.
193193+194194+ <literal>systemd-boot</literal> orders the menu entries by the config file names,
195195+ so if you want something to appear after all the NixOS entries,
196196+ it should start with <filename>o</filename> or onwards.
197197+ '';
198198+ };
199199+200200+ extraFiles = mkOption {
201201+ type = types.attrsOf types.path;
202202+ default = {};
203203+ example = literalExpression ''
204204+ { "efi/memtest86/memtest86.efi" = "''${pkgs.memtest86-efi}/BOOTX64.efi"; }
205205+ '';
206206+ description = ''
207207+ A set of files to be copied to <filename>/boot</filename>.
208208+ Each attribute name denotes the destination file name in
209209+ <filename>/boot</filename>, while the corresponding
210210+ attribute value specifies the source file.
211211+ '';
128212 };
129213130214 graceful = mkOption {
···148232 assertions = [
149233 {
150234 assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
151151-152235 message = "This kernel does not support the EFI boot stub";
153236 }
154154- ];
237237+ ] ++ concatMap (filename: [
238238+ {
239239+ assertion = !(hasInfix "/" filename);
240240+ message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries within folders are not supported";
241241+ }
242242+ {
243243+ assertion = hasSuffix ".conf" filename;
244244+ message = "boot.loader.systemd-boot.extraEntries.${lib.strings.escapeNixIdentifier filename} is invalid: entries must have a .conf file extension";
245245+ }
246246+ ]) (builtins.attrNames cfg.extraEntries)
247247+ ++ concatMap (filename: [
248248+ {
249249+ assertion = !(hasPrefix "/" filename);
250250+ message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: paths must not begin with a slash";
251251+ }
252252+ {
253253+ assertion = !(hasInfix ".." filename);
254254+ message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: paths must not reference the parent directory";
255255+ }
256256+ {
257257+ assertion = !(hasInfix "nixos/.extra-files" (toLower filename));
258258+ message = "boot.loader.systemd-boot.extraFiles.${lib.strings.escapeNixIdentifier filename} is invalid: files cannot be placed in the nixos/.extra-files directory";
259259+ }
260260+ ]) (builtins.attrNames cfg.extraFiles);
155261156262 boot.loader.grub.enable = mkDefault false;
157263158264 boot.loader.supportsInitrdSecrets = true;
265265+266266+ boot.loader.systemd-boot.extraFiles = mkMerge [
267267+ # TODO: This is hard-coded to use the 64-bit EFI app, but it could probably
268268+ # be updated to use the 32-bit EFI app on 32-bit systems. The 32-bit EFI
269269+ # app filename is BOOTIA32.efi.
270270+ (mkIf cfg.memtest86.enable {
271271+ "efi/memtest86/BOOTX64.efi" = "${pkgs.memtest86-efi}/BOOTX64.efi";
272272+ })
273273+ (mkIf cfg.netbootxyz.enable {
274274+ "efi/netbootxyz/netboot.xyz.efi" = "${pkgs.netbootxyz-efi}";
275275+ })
276276+ ];
277277+278278+ boot.loader.systemd-boot.extraEntries = mkMerge [
279279+ (mkIf cfg.memtest86.enable {
280280+ "${cfg.memtest86.entryFilename}" = ''
281281+ title MemTest86
282282+ efi /efi/memtest86/BOOTX64.efi
283283+ '';
284284+ })
285285+ (mkIf cfg.netbootxyz.enable {
286286+ "${cfg.netbootxyz.entryFilename}" = ''
287287+ title netboot.xyz
288288+ efi /efi/netbootxyz/netboot.xyz.efi
289289+ '';
290290+ })
291291+ ];
159292160293 system = {
161294 build.installBootLoader = checkedSystemdBootBuilder;
···3939 done
40404141 # Fix hard coded paths.
4242- for f in $(grep -Rl /usr/share/ src) ; do
4242+ for f in $(grep -Rl /usr/share/ src install/desktop) ; do
4343 substituteInPlace $f --replace /usr/share/ $out/share/
4444 done
4545
···11+{ lib
22+, fetchurl
33+}:
44+55+let
66+ pname = "netboot.xyz-efi";
77+ version = "2.0.53";
88+in fetchurl {
99+ name = "${pname}-${version}";
1010+1111+ url = "https://github.com/netbootxyz/netboot.xyz/releases/download/${version}/netboot.xyz.efi";
1212+ sha256 = "sha256-v7XqrhG94BLTpDHDazTiowQUXu/ITEcgVMmhlqgmSQE=";
1313+1414+ meta = with lib; {
1515+ homepage = "https://netboot.xyz/";
1616+ description = "A tool to boot OS installers and utilities over the network, to be run from a bootloader";
1717+ license = licenses.asl20;
1818+ maintainers = with maintainers; [ Enzime ];
1919+ platforms = platforms.linux;
2020+ };
2121+}