about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/system/boot/loader/raspberrypi/raspberrypi.nix
blob: 9c9bee93de8adb3eb742d3e400d83077dc84587f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.boot.loader.raspberryPi;

  builderUboot = import ./uboot-builder.nix { inherit pkgs configTxt; inherit (cfg) version; };
  builderGeneric = import ./raspberrypi-builder.nix { inherit pkgs configTxt; };

  builder =
    if cfg.uboot.enable then
      "${builderUboot} -g ${toString cfg.uboot.configurationLimit} -t ${timeoutStr} -c"
    else
      "${builderGeneric} -c";

  blCfg = config.boot.loader;
  timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;

  isAarch64 = pkgs.stdenv.hostPlatform.isAarch64;
  optional = pkgs.lib.optionalString;

  configTxt =
    pkgs.writeText "config.txt" (''
      # U-Boot used to need this to work, regardless of whether UART is actually used or not.
      # TODO: check when/if this can be removed.
      enable_uart=1

      # Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
      # when attempting to show low-voltage or overtemperature warnings.
      avoid_warnings=1
    '' + optional isAarch64 ''
      # Boot in 64-bit mode.
      arm_64bit=1
    '' + (if cfg.uboot.enable then ''
      kernel=u-boot-rpi.bin
    '' else ''
      kernel=kernel.img
      initramfs initrd followkernel
    '') + optional (cfg.firmwareConfig != null) cfg.firmwareConfig);

in

{
  options = {

    boot.loader.raspberryPi = {
      enable = mkOption {
        default = false;
        type = types.bool;
        description = lib.mdDoc ''
          Whether to create files with the system generations in
          `/boot`.
          `/boot/old` will hold files from old generations.

          ::: {.note}
          These options are deprecated, unsupported, and may not work like expected.
          :::
        '';
      };

      version = mkOption {
        default = 2;
        type = types.enum [ 0 1 2 3 4 ];
        description = lib.mdDoc "";
      };

      uboot = {
        enable = mkOption {
          default = false;
          type = types.bool;
          description = lib.mdDoc ''
            Enable using uboot as bootmanager for the raspberry pi.

            ::: {.note}
            These options are deprecated, unsupported, and may not work like expected.
            :::
          '';
        };

        configurationLimit = mkOption {
          default = 20;
          example = 10;
          type = types.int;
          description = lib.mdDoc ''
            Maximum number of configurations in the boot menu.

            ::: {.note}
            These options are deprecated, unsupported, and may not work like expected.
            :::
          '';
        };

      };

      firmwareConfig = mkOption {
        default = null;
        type = types.nullOr types.lines;
        description = lib.mdDoc ''
          Extra options that will be appended to `/boot/config.txt` file.
          For possible values, see: https://www.raspberrypi.com/documentation/computers/config_txt.html

          ::: {.note}
          These options are deprecated, unsupported, and may not work like expected.
          :::
        '';
      };
    };
  };

  config = mkMerge[
    (mkIf cfg.uboot.enable {
      warnings = [
        ''
          The option set for `boot.loader.raspberrypi.uboot` has been recommended against
          for years, and is now formally deprecated.

          It is possible it already did not work like you expected.

          It never worked on the Raspberry Pi 4 family.

          These options will be removed by NixOS 24.11.
        ''
      ];
    })
    (mkIf cfg.enable {
      warnings = [
        ''
          The option set for `boot.loader.raspberrypi` has been recommended against
          for years, and is now formally deprecated.

          It is possible it already did not work like you expected.

          It never worked on the Raspberry Pi 4 family.

          These options will be removed by NixOS 24.11.
        ''
      ];
    })
    (mkIf cfg.enable {
      assertions = singleton {
        assertion = !pkgs.stdenv.hostPlatform.isAarch64 || cfg.version >= 3;
        message = "Only Raspberry Pi >= 3 supports aarch64.";
      };

      system.build.installBootLoader = builder;
      system.boot.loader.id = "raspberrypi";
      system.boot.loader.kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
    })
  ];
}