Skip to content

Conversation

@qbisi
Copy link
Contributor

@qbisi qbisi commented Sep 27, 2025

grub do have support for loading deviceTree from filesystem and pass it to linux.
See https://www.gnu.org/software/grub/manual/grub/html_node/devicetree.html.
Here we implement deviceTree support for grub module.

Things done

  1. Fix efi_uga module not available on aarch64-linux platform when using grub. (efi_uga is only available on x86)
  2. Add support for nixos grub module to load deviceTree if hardware.deviceTree.name is specified.
  3. The option boot.loader.loadDeviceTree, renamed from boot.loader.systemd-boot.installDeviceTree, now provides generic device tree loading support for bootloaders.
  4. A new bootspec field, org.nixos.grub, is introduced to store generation’s device-tree information.

Future plan

  1. implement deviceTree support for limine
  2. [RFC] migrate the systemd-boot bootspec field "org.nixos.systemd-boot".deviceTree to "org.nixos.bootspec.v2".deviceTree. It will just work with a simple replacement, however it brokes compatibility with legacy configuration and prevent rolling back to legacy onfiguration.
  3. make generic-exlinux to use bootspec "org.nixos.bootspec.v2"

cc @jfly @jmbaur for your comment.

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-nixos-tests This PR causes rebuilds for all NixOS tests and should normally target the staging branches. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Sep 27, 2025
@nix-owners nix-owners bot requested a review from JulienMalka September 27, 2025 07:49
@qbisi qbisi force-pushed the nixos/grub branch 2 times, most recently from a00acb8 to d25b074 Compare September 27, 2025 08:01
@qbisi
Copy link
Contributor Author

qbisi commented Sep 27, 2025

nixpkgs-review result

Generated using nixpkgs-review.

Command: nixpkgs-review pr 446563 --package nixosTests.device-tree.grub --package nixosTests.device-tree.systemd-boot
Commit: d25b07436cf1ab96f9e8014a44ab97673cc13a87


aarch64-linux

✅ 2 tests built:
  • nixosTests.device-tree.grub
  • nixosTests.device-tree.systemd-boot

@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Oct 2, 2025
@nixpkgs-ci nixpkgs-ci bot removed the 2.status: merge conflict This PR has merge conflicts with the target branch label Oct 3, 2025
Copy link
Contributor

@jfly jfly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not my area of expertise, sorry. I'll leave it to @jmbaur to give a proper review.

One high level question: how does this PR relate to #439700 and #403746?

@qbisi
Copy link
Contributor Author

qbisi commented Oct 7, 2025

One high level question: how does this PR relate to #439700 and #403746?

#439700 and #446563 are independant implemention of device-tree support for grub. Just make sure we use the same option boot.loader.loadDeviceTree.

#403746 will be closed and reimplemented after #446563. kernel maintainers do not agree on keeping extra *.dtsi files. Debian also does not keep *.dtsi files in their kbuild package. So i will seek other ways (e.g. using pkgs.srcOnly).

@jmbaur
Copy link
Contributor

jmbaur commented Oct 12, 2025

It seems that adding a boot.loader.loadDeviceTree option would make the extlinux module inconsistent in the sense that it would not be respecting this option, since it doesn't even use it. Though given that the extlinux module is inconsistent in other ways (e.g. it doesn't install specialisations), I don't think there's much we should do about that here.

@@ -465,6 +467,13 @@ sub addEntry {

my $kernel = copyToKernelsDir(Cwd::abs_path("$path/kernel"));
my $initrd = copyToKernelsDir(Cwd::abs_path("$path/initrd"));
my $json_text = read_file("$path/boot.json");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are already consuming the bootspec file here, it would also make sense to pull the kernel and initrd from here

Copy link
Contributor Author

@qbisi qbisi Oct 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You remind me, i think it is more appropriate we use bootspec "org.nixos.boot" instead of "org.nixos.device-tree" here, as it allows us to include more information (e.g. kernel initrd) in it.
However, this won’t be an easy migration. We still need backward compatibility for generations that currently place the kernel and initrd under $path, and we should warn users when we will drop the backward compatiblity. The same difficulty happen if we want migrate bootspec "org.nixos.systemd-boot".devicetree to "org.nixos.boot".devicetree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There already exists "org.nixos.bootspec.v1", we can put devicetree information under it.

@nixpkgs-ci nixpkgs-ci bot added the 12.approvals: 1 This PR was reviewed and approved by one person. label Oct 12, 2025
@qbisi
Copy link
Contributor Author

qbisi commented Oct 12, 2025

It seems that adding a boot.loader.loadDeviceTree option would make the extlinux module inconsistent in the sense that it would not be respecting this option, since it doesn't even use it. Though given that the extlinux module is inconsistent in other ways (e.g. it doesn't install specialisations), I don't think there's much we should do about that here.

builderArgs =
"-g ${toString cfg.configurationLimit} -t ${timeoutStr}"
+ lib.optionalString (dtCfg.name != null) " -n ${dtCfg.name}"
+ lib.optionalString (!cfg.useGenerationDeviceTree) " -r";
installBootLoader = pkgs.writeScript "install-extlinux-conf.sh" (

by replacing (dtCfg.name != null) with config.boot.loader.loadDeviceTree we can make it somehow consistent.
However extlinux module made the assumption that every generation use the same deviceTree.name as the current active profile, then it load the fdtfile from per generations' $path/dtb directory. That's why it does not make use of bootspec file.

@qbisi qbisi requested a review from Mic92 October 12, 2025 21:33
The insmod efi_gop and insmod efi_uga directives load two modules for
EFI-based video support. On most systems the efi_gop module is enough.
The efi_uga module is only useful and available for legacy system on
i386 and x86_64. Therefore, we load the efi_uga module conditionally.
@@ -35,6 +35,9 @@ let
}
// lib.optionalAttrs hasAtLeastOneInitrdSecret {
initrdSecrets = "${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets";
}
Copy link
Member

@cole-h cole-h Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (devicetree) is not a field in the V1 bootspec specification (https://github.com/NixOS/rfcs/blob/master/rfcs/0125-bootspec.md#bootspec-format-v1), so it should not be under the versioned org.nixos.bootspec.v1 key.

This should probably be an extension instead, or proposed as part of a V2 format of bootspec (there is an existing RFC for this at NixOS/rfcs#165).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like the key to be under the field org.nixos.bootspec.v2, should i wait until the RFC NixOS/rfcs#165 been merged?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you'll want to wait for RFC 165 to merge if that's the case. However, since it's still a draft, you should not rely on it in this PR, as it may still change before it's merged.

Copy link
Contributor Author

@qbisi qbisi Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeking other bootspec field other than "org.nixos.bootspec.v2" will make it hard for users to migrate their legacy configuration when we switch to bootspec v2.

Copy link
Member

@cole-h cole-h Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean by "migrate their legacy configuration" -- old generations will have an extension for the devicetree (since it's not part of v1, and v2 has not been merged yet), and everything from Nixpkgs will understand it because it will be the same Nixpkgs revision that generated the boot.json with the extension for devicetree.

New generations (once v2 is merged) will have the "org.nixos.bootspec.v2".devicetree key accessible, and Nixpkgs will understand that at that point.

Additionally, there exists a synthesize tool whose job is to go from "no bootspec" or "bootspec vX" to "bootspec v(X+Y)" for the purposes of these bootloader generators, see:

It will be updated for bootspec v2 once bootspec v2 merges.


All that, in addition to the fact that this is exactly what extensions were intended for, makes me feel very strongly that this PR should either: 1) not use the bootspec document and pass the device tree in to the bootloader generators some other way; or 2) create an extension for it that does not abuse the versioned org.nixos.bootspec.vX namespace and access it that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will use the generation of grub.cfg as a example.
grub.cfg contains information of all the generation's kernel/initrd path (and devcietree path if this pr get merged).
It is generated by the current (most likely the latest) generation's nixpkgs install-grub.pl script. This script translate per generation's bootspec "org.nixos.somefield".devicetree to corresbonding devicetree /nix/store/xxxxx.dtb command. It is supposed to provide backward compatibility with old generation's boot.json when we switch to "org.nixos.bootsepc.v2".devicetree. It will be painfull we notify users when we will drop this backward compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you expect these generators to run on mismatched Nixpkgs versions (i.e. the system was created with a Nixpkgs with v2 of bootspec, but the generator only understands v1+this extension)?

I expect the old system was created with a Nixpkgs with v1+this extension, but the generator only understands v2.

Copy link
Contributor Author

@qbisi qbisi Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cole-h

Do we still argue that the migration from org.nixos.systemd-boot.devicetree to org.nixos.bootspec.v2.devicetree migth (or not) be a problem

nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py

bootspec_json.get('org.nixos.systemd-boot', {}) -> bootspec_json.get('org.nixos.bootspec.v2', {}) 

I think this simple migration will drop backward compatibility with old generation that use org.nixos.systemd-boot.devicetree. (So we have to use fallback logical for a while)

What do you think about the right way to push this pr forward. also ping @jmbaur for suggestion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For systemd-boot, I think it's probably not a problem because each boot entry can be generated individually.

I forgot about the grub "quirk" where it has to generate all the boot options every time (ugh).

That said, it sounds like it would probably be best to add an org.nixos.grub.deviceTree extension to the bootspec. Once v2 is adopted, then grub can use org.nixos.bootspec.v2.devicetree (or whatever it ends up being) if it exists, or org.nixos.grub.deviceTree if that doesn't exist. We'd keep generating org.nixos.grub.deviceTree, at least for a release or two.

This approach should keep everything working even once v2 is adopted.

Copy link
Contributor Author

@qbisi qbisi Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For systemd-boot, I think it's probably not a problem because each boot entry can be generated individually.

Got it. I will use org.nixos.grub.deviceTree as a temporaroy solution.

Btw, when we will reach an agreement on bootspec v2. Does community have any plan to disscuss NixOS/rfcs#165 in the meeting.

Rename `boot.loader.systemd-boot.installDeviceTree`
to `boot.loader.loadDeviceTree`. This option provides
generic support for loading device trees.
@qbisi
Copy link
Contributor Author

qbisi commented Oct 22, 2025

nixpkgs-review result

Generated using nixpkgs-review.

Command: nixpkgs-review pr 446563 --package nixosTests.device-tree.systemd-boot --package nixosTests.device-tree.grub
Commit: 7a0c81709079bd6b16fecdc52a023218d0abd540


aarch64-linux

✅ 2 tests built:
  • nixosTests.device-tree.grub
  • nixosTests.device-tree.systemd-boot

@mdaniels5757 mdaniels5757 changed the base branch from master to staging-nixos January 18, 2026 03:39
@nixpkgs-ci nixpkgs-ci bot closed this Jan 18, 2026
@nixpkgs-ci nixpkgs-ci bot reopened this Jan 18, 2026
@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-nixos-tests This PR causes rebuilds for all NixOS tests and should normally target the staging branches. 12.approvals: 1 This PR was reviewed and approved by one person.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants