From 19a8570ec93e861d752fc5d84cf1a516e4057187 Mon Sep 17 00:00:00 2001 From: Travis Staton Date: Wed, 24 Jan 2024 11:16:46 -0500 Subject: [PATCH] booting --- rpi/default.nix | 74 ++++++++++++++++++++++++++++++++++++++++---- sd-image/default.nix | 52 ++++++++++++++++++++++++------- 2 files changed, 108 insertions(+), 18 deletions(-) diff --git a/rpi/default.nix b/rpi/default.nix index 6ed0563..f1e3087 100644 --- a/rpi/default.nix +++ b/rpi/default.nix @@ -1,6 +1,8 @@ { core-overlay, libcamera-overlay }: { lib, pkgs, config, ... }: +let cfg = config.raspberry-pi-nix; +in { imports = [ ../sd-image ./config.nix ./i2c.nix ]; @@ -18,18 +20,41 @@ type = types.bool; }; }; + uboot = { + enable = mkOption { + default = true; + type = types.bool; + }; + }; }; }; config = { + boot.kernelParams = + if cfg.uboot.enable then [ ] + else [ + "root=PARTUUID=2178694e-02" # todo: use option + "rootfstype=ext4" + "fsck.repair=yes" + "rootwait" + "init=/sbin/init" + ]; systemd.services = { "raspberry-pi-firmware-migrate" = - lib.mkIf config.raspberry-pi-nix.firmware-migration-service.enable { + { description = "update the firmware partition"; - wantedBy = [ "multi-user.target" ]; + wantedBy = if cfg.firmware-migration-service.enable then [ "multi-user.target" ] else [ ]; serviceConfig = - let firmware-path = "/boot/firmware"; - in { + let + firmware-path = "/boot/firmware"; + kernel-params = pkgs.writeTextFile { + name = "cmdline.txt"; + text = '' + ${lib.strings.concatStringsSep " " config.boot.kernelParams} + ''; + }; + in + { Type = "oneshot"; MountImages = "/dev/disk/by-label/${config.sdImage.firmwarePartitionName}:${firmware-path}"; @@ -41,6 +66,8 @@ TARGET_OVERLAYS_DIR="$TARGET_FIRMWARE_DIR/overlays" TMPFILE="$TARGET_FIRMWARE_DIR/tmp" UBOOT="${pkgs.uboot_rpi_arm64}/u-boot.bin" + KERNEL="${pkgs.rpi-kernels.latest.kernel}/Image" + SHOULD_UBOOT=${if cfg.uboot.enable then "1" else "0"} SRC_FIRMWARE_DIR="${pkgs.raspberrypifw}/share/raspberrypi/boot" STARTFILES=("$SRC_FIRMWARE_DIR"/start*.elf) DTBS=("$SRC_FIRMWARE_DIR"/*.dtb) @@ -61,6 +88,28 @@ rm "$STATE_DIRECTORY/uboot-migration-in-progress" } + migrate_kernel() { + echo "migrating kernel" + touch "$STATE_DIRECTORY/kernel-migration-in-progress" + cp "$KERNEL" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/kernel.img" + echo "${ + builtins.toString pkgs.rpi-kernels.latest.kernel + }" > "$STATE_DIRECTORY/kernel-version" + rm "$STATE_DIRECTORY/kernel-migration-in-progress" + } + + migrate_cmdline() { + echo "migrating cmdline" + touch "$STATE_DIRECTORY/cmdline-migration-in-progress" + cp "${kernel-params}" "$TMPFILE" + mv -T "$TMPFILE" "$TARGET_FIRMWARE_DIR/cmdline.txt" + echo "${ + builtins.toString kernel-params + }" > "$STATE_DIRECTORY/cmdline-version" + rm "$STATE_DIRECTORY/cmdline-migration-in-progress" + } + migrate_config() { echo "migrating config.txt" touch "$STATE_DIRECTORY/config-migration-in-progress" @@ -94,12 +143,24 @@ rm "$STATE_DIRECTORY/firmware-migration-in-progress" } - if [[ -f "$STATE_DIRECTORY/uboot-migration-in-progress" || ! -f "$STATE_DIRECTORY/uboot-version" || $(< "$STATE_DIRECTORY/uboot-version") != ${ + if [[ "$SHOULD_UBOOT" -eq 1 ]] && [[ -f "$STATE_DIRECTORY/uboot-migration-in-progress" || ! -f "$STATE_DIRECTORY/uboot-version" || $(< "$STATE_DIRECTORY/uboot-version") != ${ builtins.toString pkgs.uboot_rpi_arm64 } ]]; then migrate_uboot fi + if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/kernel-version" || $(< "$STATE_DIRECTORY/kernel-version") != ${ + builtins.toString pkgs.rpi-kernels.latest.kernel + } ]]; then + migrate_kernel + fi + + if [[ "$SHOULD_UBOOT" -ne 1 ]] && [[ ! -f "$STATE_DIRECTORY/cmdline-version" || $(< "$STATE_DIRECTORY/cmdline-version") != ${ + builtins.toString kernel-params + } ]]; then + migrate_cmdline + fi + if [[ -f "$STATE_DIRECTORY/config-migration-in-progress" || ! -f "$STATE_DIRECTORY/config-version" || $(< "$STATE_DIRECTORY/config-version") != ${ builtins.toString config.hardware.raspberry-pi.config-output } ]]; then @@ -194,8 +255,9 @@ loader = { grub.enable = lib.mkDefault false; + initScript.enable = !cfg.uboot.enable; generic-extlinux-compatible = { - enable = lib.mkDefault true; + enable = lib.mkDefault cfg.uboot.enable; # We want to use the device tree provided by firmware, so don't # add FDTDIR to the extlinux conf file. useGenerationDeviceTree = false; diff --git a/sd-image/default.nix b/sd-image/default.nix index 2804d06..c14e50b 100644 --- a/sd-image/default.nix +++ b/sd-image/default.nix @@ -5,23 +5,51 @@ config = { boot.loader.grub.enable = false; - boot.loader.generic-extlinux-compatible.enable = true; boot.consoleLogLevel = lib.mkDefault 7; # https://github.com/raspberrypi/firmware/issues/1539#issuecomment-784498108 boot.kernelParams = [ "console=serial0,115200n8" "console=tty1" ]; - sdImage = { - populateFirmwareCommands = '' - cp ${pkgs.uboot_rpi_arm64}/u-boot.bin firmware/u-boot-rpi-arm64.bin - cp -r ${pkgs.raspberrypifw}/share/raspberrypi/boot/{start*.elf,*.dtb,bootcode.bin,fixup*.dat,overlays} firmware - cp ${config.hardware.raspberry-pi.config-output} firmware/config.txt - ''; - populateRootCommands = '' - mkdir -p ./files/boot - ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot - ''; - }; + sdImage = + let + kernel-params = pkgs.writeTextFile { + name = "cmdline.txt"; + text = '' + ${lib.strings.concatStringsSep " " config.boot.kernelParams} + ''; + }; + populate-kernel = + if config.raspberry-pi-nix.uboot.enable + then '' + cp ${pkgs.uboot_rpi_arm64}/u-boot.bin firmware/u-boot-rpi-arm64.bin + '' + else '' + cp "${pkgs.rpi-kernels.latest.kernel}/Image" firmware/kernel.img + cp "${kernel-params}" firmware/cmdline.txt + ''; + in + { + populateFirmwareCommands = '' + ${populate-kernel} + cp -r ${pkgs.raspberrypifw}/share/raspberrypi/boot/{start*.elf,*.dtb,bootcode.bin,fixup*.dat,overlays} firmware + cp ${config.hardware.raspberry-pi.config-output} firmware/config.txt + ''; + populateRootCommands = + if config.raspberry-pi-nix.uboot.enable + then '' + mkdir -p ./files/boot + ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d ./files/boot + '' + else '' + mkdir -p ./files/sbin + content="$( + echo "#!${config.system.build.toplevel.pkgs.bashInteractive}/bin/bash" + echo "exec ${config.system.build.toplevel}/init" + )" + echo "$content" > ./files/sbin/init + chmod 744 ./files/sbin/init + ''; + }; }; }