nixos/systemd-boot: add support for devicetree entry
The [Boot Loader Specification](https://uapi-group.org/specifications/specs/boot_loader_specification/) allows for using a key called "devicetree" for specifying which devicetree the bootloader should use during boot. With regards to systemd-boot, this key is used to specify which file should be picked up from the ESP to install to the EFI DTB Configuration Table. Linux then uses this Configuration Table to setup the machine. This change is similar to the one done in https://github.com/NixOS/nixpkgs/pull/295096, where that change was for adding DTB support to systemd-stub, and this is for systemd-boot.
This commit is contained in:
parent
6614b28fa9
commit
fca8ee915d
@ -47,6 +47,7 @@ class BootSpec:
|
||||
toplevel: str
|
||||
specialisations: dict[str, "BootSpec"]
|
||||
sortKey: str # noqa: N815
|
||||
devicetree: str | None = None # noqa: N815
|
||||
initrdSecrets: str | None = None # noqa: N815
|
||||
|
||||
@dataclass
|
||||
@ -84,6 +85,7 @@ class DiskEntry:
|
||||
kernel_params: str | None
|
||||
machine_id: str | None
|
||||
sort_key: str
|
||||
devicetree: str | None
|
||||
|
||||
@classmethod
|
||||
def from_path(cls: Type["DiskEntry"], path: Path) -> "DiskEntry":
|
||||
@ -108,7 +110,9 @@ class DiskEntry:
|
||||
initrd=entry_map["initrd"],
|
||||
kernel_params=entry_map.get("options"),
|
||||
machine_id=entry_map.get("machine-id"),
|
||||
sort_key=entry_map.get("sort_key", "nixos"))
|
||||
sort_key=entry_map.get("sort_key", "nixos"),
|
||||
devicetree=entry_map.get("devicetree"),
|
||||
)
|
||||
return disk_entry
|
||||
|
||||
def write(self, sorted_first: str) -> None:
|
||||
@ -127,7 +131,8 @@ class DiskEntry:
|
||||
f"initrd {self.initrd}",
|
||||
f"options {self.kernel_params}" if self.kernel_params is not None else None,
|
||||
f"machine-id {self.machine_id}" if self.machine_id is not None else None,
|
||||
f"sort-key {default_sort_key if self.default else self.sort_key}"
|
||||
f"sort-key {default_sort_key if self.default else self.sort_key}",
|
||||
f"devicetree {self.devicetree}" if self.devicetree is not None else None,
|
||||
]
|
||||
|
||||
f.write("\n".join(filter(None, boot_entry)))
|
||||
@ -233,10 +238,12 @@ def bootspec_from_json(bootspec_json: dict[str, Any]) -> BootSpec:
|
||||
specialisations = {k: bootspec_from_json(v) for k, v in specialisations.items()}
|
||||
systemdBootExtension = bootspec_json.get('org.nixos.systemd-boot', {})
|
||||
sortKey = systemdBootExtension.get('sortKey', 'nixos')
|
||||
devicetree = systemdBootExtension.get('devicetree')
|
||||
return BootSpec(
|
||||
**bootspec_json['org.nixos.bootspec.v1'],
|
||||
specialisations=specialisations,
|
||||
sortKey=sortKey
|
||||
sortKey=sortKey,
|
||||
devicetree=devicetree,
|
||||
)
|
||||
|
||||
|
||||
@ -261,6 +268,7 @@ def write_entry(profile: str | None,
|
||||
bootspec = bootspec.specialisations[specialisation]
|
||||
kernel = copy_from_file(bootspec.kernel)
|
||||
initrd = copy_from_file(bootspec.initrd)
|
||||
devicetree = copy_from_file(bootspec.devicetree) if bootspec.devicetree is not None else None
|
||||
|
||||
title = "{name}{profile}{specialisation}".format(
|
||||
name=DISTRO_NAME,
|
||||
@ -303,6 +311,7 @@ def write_entry(profile: str | None,
|
||||
machine_id=machine_id,
|
||||
description=f"Generation {generation} {bootspec.label}, built on {build_date}",
|
||||
sort_key=bootspec.sortKey,
|
||||
devicetree=devicetree,
|
||||
default=current
|
||||
).write(sorted_first)
|
||||
|
||||
|
@ -191,6 +191,15 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
installDeviceTree = mkOption {
|
||||
default = with config.hardware.deviceTree; enable && name != null;
|
||||
defaultText = ''with config.hardware.deviceTree; enable && name != null'';
|
||||
description = ''
|
||||
Install the devicetree blob specified by `config.hardware.deviceTree.name`
|
||||
to the ESP and instruct systemd-boot to pass this DTB to linux.
|
||||
'';
|
||||
};
|
||||
|
||||
extraInstallCommands = mkOption {
|
||||
default = "";
|
||||
example = ''
|
||||
@ -353,6 +362,10 @@ in {
|
||||
assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
|
||||
message = "This kernel does not support the EFI boot stub";
|
||||
}
|
||||
{
|
||||
assertion = cfg.installDeviceTree -> config.hardware.deviceTree.enable -> config.hardware.deviceTree.name != null;
|
||||
message = "Cannot install devicetree without 'config.hardware.deviceTree.enable' enabled and 'config.hardware.deviceTree.name' set";
|
||||
}
|
||||
] ++ concatMap (filename: [
|
||||
{
|
||||
assertion = !(hasInfix "/" filename);
|
||||
@ -410,6 +423,7 @@ in {
|
||||
|
||||
boot.bootspec.extensions."org.nixos.systemd-boot" = {
|
||||
inherit (config.boot.loader.systemd-boot) sortKey;
|
||||
devicetree = lib.mkIf cfg.installDeviceTree "${config.hardware.deviceTree.package}/${config.hardware.deviceTree.name}";
|
||||
};
|
||||
|
||||
system = {
|
||||
|
Loading…
Reference in New Issue
Block a user