LINUX.ORG.RU

Избранные сообщения Abbadon

NixOS 25.05 (Warbler) на Raspberry Pi 5

Форум — Talks

Если внезапно кто-то захочет пройти этим путём… В общем держу в курсе.

OS и софт:

NixOS with Flakes, Disko, impermanence rootless (aka Erase your darlings), home-manager а главное Nix flake for a fully declarative NixOS on Raspberry Pi

Ванильное ядро Linux не увидит PCIe а соотвественно и nvme/ssd диски. В то же время nvmd/nixos-raspberrypi сделал нам хорошо опакетив форк ядра и загрузчик от малины.

Использованное железо:

https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#enable-pcie

В configtxt.nix

  pciex1 = {
    enable = true;
    value = "on";
  };

https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0

В configtxt.nix

  pciex1_gen = {
    enable = true;
    value = "3";
  };

https://www.raspberrypi.com/documentation/computers/configuration.html usb_max_current_enable

Zero if the USB port current limiter was set to the low-limit during boot; or non-zero if the high limit was enabled. The high level is automatically enabled if the power supply claims 5A max-current OR usb_max_current_enable=1 is forced in config.txt

В configtxt.nix

  usb_max_current_enable = {
    enable = lib.mkDefault true;
    value = lib.mkDefault true;
  };

Загрузочная sd карточка:

Cклонировали репу, внимательно прочитали README.md, Да modules/configtxt.nix добавили ssh ключи и нужный софт. Собственно сборка nix build .#installerImages.rpi5

Результат:

> du -h result/sd-image/nixos-installer-rpi5-kernel.img.zst
1,5G    result/sd-image/nixos-installer-rpi5-kernel.img.zst

Дальше банально:

> unxz result/sd-image/nixos-installer-rpi5-kernel.img.zst
> dd if=result/sd-image/nixos-installer-rpi5-kernel.img | pv | dd of=/dev/СМОТРИ_НЕ_ПЕРЕПУТАЙ_КУДА

В установленной системе:

Абстрактный однако, при этом, рабочий пример Disko.nix для двух дисковой установки (ssd поменьше под ОС, ssd побольше под данные) с корнем в ram.

{
  disko.devices = {
    nodev."/" = {
      fsType = "tmpfs";
      mountOptions = [
        "defaults"
        "size=2G"
        "mode=755"
      ];
    };

    disk = {
      main = {
        type = "disk";
        device = "/dev/nvme0n1";
        content = {
          type = "gpt";
          partitions = {

            ESP = {
              priority = 1;
              name = "ESP";
              label = "ESP";
              start = "1M";
              end = "2048M";
              type = "EF00";
              content = {
                type = "filesystem";
                format = "vfat";
                mountOptions = [
                  "noatime"
                  "nodiratime"
                  "umask=077"
                ];
                mountpoint = "/boot";
              };
            };

            nyx = {
              size = "100%";
              name = "MY_NAME";
              label = "MY_NAME";
              content = {
                type = "btrfs";
                extraArgs = [
                  "--label MY_NAME"
                  "-f"
                  "--csum xxhash64"
                  "--features"
                  "block-group-tree"
                ];
                subvolumes = {
                  "home" = {
                    mountpoint = "/home";
                    mountOptions = [
                      "subvol=home"
                      "compress=zstd"
                      "noatime"
                      "ssd"
                      "discard=async"
                      "space_cache=v2"
                    ];
                  };
                  "nix" = {
                    mountpoint = "/nix";
                    mountOptions = [
                      "subvol=nix"
                      "compress=zstd"
                      "noatime"
                      "ssd"
                      "discard=async"
                      "space_cache=v2"
                      "nodev"
                      "nosuid"
                    ];
                  };
                  "log" = {
                    mountpoint = "/var/log";
                    mountOptions = [
                      "subvol=log"
                      "compress=zstd"
                      "noatime"
                      "ssd"
                      "space_cache=v2"
                    ];
                  };
                  tmp = {
                    mountpoint = "/tmp";
                    mountOptions = [ "noatime" ];
                  };

                };
              };
            };

          };
        };
      };
    };

    disk = {
      media = {
        type = "disk";
        device = "/dev/nvme1n1";
        content = {
          type = "gpt";
          partitions = {

            media = {
              size = "100%";
              name = "media";
              label = "media";
              content = {
                type = "btrfs";
                extraArgs = [
                  "--label media"
                  "-f"
                  "--csum xxhash64"
                  "--features"
                  "block-group-tree"
                ];
                subvolumes = {
                  "media" = {
                    mountpoint = "/NAS";
                    mountOptions = [
                      "subvol=media"
                      "compress=zstd"
                      "noatime"
                      "ssd"
                      "discard=async"
                      "space_cache=v2"
                    ];
                  };

                };
              };
            };

          };
        };
      };
    };


  };

  fileSystems = {
    "/var/log".neededForBoot = true;
  };
}

Уничтожение (!!!) всех данных и создание всех разделов на всех дисках:

nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode destroy,format,mount Disko.nix

Монтирование всех разделов на всех дисках из live sdcart

nix --experimental-features "nix-command flakes" run github:nix-community/disko/latest -- --mode mount Disko.nix

Из остального, что является существенным, я поправил:

  boot.tmp.useTmpfs = true;
  boot.loader.raspberryPi.bootloader = "kernel";
  boot.loader.raspberryPi.firmwarePath = "/boot"; # /boot/firmware
  boot.kernelParams = [ "console=serial0,115200n8" "console=tty1" "cfg80211.ieee80211_regdom=RU" ];

Выводы

Всё прочее банально, зависит от привычек и вкуса и не требует пояснений. Пациент с описанным сетапом жив. Однако да решение требует пердолинга, свободного времени и желания. За полумесячный период эксплуатации замечены два полных внезапных вайпа системы после обновлений nixos-rebuild switch --flake .#${HOSTNAME} -L и последующей перезагрузки. Причины не выяснены. Мой прогноз - пока что аппстрим NixOS это не примет. Возможно примет позже когда 5ю малину будет поддерживать uboot и ванильное ядро. Всем чмоки в этам чатики. Поздравляю всех выживших с наступившим.

 , ,

init_6
()