Files
nix-files/modules/system/boot/loader/raspberrypi/raspberrypi.nix
Colin 1064867194 migrate the nix install to an external USB drive.
this requires a patch to uboot:
- uboot thinks the drive has a capacity of 0 (i.e. 'unknown'). unclear precisely why. could be noncompliant drive firmware, or a timeout somewhere.

and a patch to the rpi bootloader:
- in order to trampoline into the rpi-4 uboot.

and custom kernel modules in the initrd:
- in order to detect the USB hub (rpi fw).

additionally, i'm MANUALLY placing `bcm2711-rpi-400.dtb` into `/boot/nixos/..-linux-5.10.111-dtbs/broadcom`.
i'll want to do this automatically over time.

i hope to simplify much of this over time: this is just the first thing which works after a couple days of hacking at it.
2022-05-17 01:58:12 +00:00

102 lines
2.8 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.boot.loader.raspberryPiColin;
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.raspberryPiColin = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Whether to create files with the system generations in
<literal>/boot</literal>.
<literal>/boot/old</literal> will hold files from old generations.
'';
};
version = mkOption {
default = 2;
type = types.enum [ 0 1 2 3 4 ];
description = "";
};
uboot = {
enable = mkOption {
default = false;
type = types.bool;
description = ''
Enable using uboot as bootmanager for the raspberry pi.
'';
};
configurationLimit = mkOption {
default = 20;
example = 10;
type = types.int;
description = ''
Maximum number of configurations in the boot menu.
'';
};
};
firmwareConfig = mkOption {
default = null;
type = types.nullOr types.lines;
description = ''
Extra options that will be appended to <literal>/boot/config.txt</literal> file.
For possible values, see: https://www.raspberrypi.org/documentation/configuration/config-txt/
'';
};
};
};
config = mkIf cfg.enable {
system.build.installBootLoader = builder;
system.boot.loader.id = "raspberrypi";
system.boot.loader.kernelFile = pkgs.stdenv.hostPlatform.linux-kernel.target;
};
}