I have been following this guide to create a headless sd image for my raspberry pi 3 B. It works great and I can create a bootable nixos on my pi3 and I can ssh into it perfectly fine.
For context:
- The method I’m using to create the sd image is with https://github.com/nix-community/nixos-generators and with this patch: nixos/lib/make-ext4-fs: use mkfs.ext4 instead of cptofs by misuzu · Pull Request #82718 · NixOS/nixpkgs · GitHub. Command:
nixos-generate -f sd-aarch64-installer --system aarch64-linux -c ./pi3-sd.nix -I nixpkgs=./nixpkgs --cores 8
- I’m using
pkgs.linuxPackages_latest
sincepkgs.linuxPackages_rpi3
doesn’t work for me. Possibly related with this: Raspberry Pi 3 B+ doesn't boot on kernel 5.4.23 · Issue #82455 · NixOS/nixpkgs · GitHub - nixpkgs is at
release-20.03
brach
Steps I take to install a new nixos configuration:
-
mkdir /boot/firmware && mount /dev/disk/by-label/FIRMWARE /boot/firmware
- I mount
/dev/disk/by-label/FIRMWARE
to/boot/firmware
since that is what <nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix> uses as a default for the firmware partition path.
- I mount
-
I
scp
over the machine specific /etc/nixos/configuration.nix and I runnixos-rebuild boot
(switch sometimes doesn’t work but that is for another post). The machine configuration.nix has the following:
/etc/nixos/configuration.nix
- Reboot
{ config, pkgs, lib, ... }:
{
imports = [
#/etc/nixos/hardware-configuration.nix # not importing this for now, see config.fileSystems
/etc/nixos/common.nix # contains ssh, wireless configs, and pkgs
];
hardware = {
enableRedistributableFirmware = true;
firmware = [ pkgs.wireless-regdb ];
};
# Defining fileSystems here allow sme to not have to run nixos-generate-config
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
fsType = "ext4";
};
"/boo/firmware" = {
device = "/dev/disk/by-uuid/2178-694E";
fsType = "vfat";
};
};
boot = {
#kernelPackages = pkgs.linuxPackages_rpi3;
kernelPackages = pkgs.linuxPackages_latest;
kernelParams = ["cma=32M"];
loader = {
grub.enable = false;
systemd-boot.enable = true;
raspberryPi.firmwareConfig = ''
boot_delay=1
'';
efi.canTouchEfiVariables = true;
timeout = 1;
};
extraModprobeConfig = ''
options cf680211 ieee80211_regdom="GB"
'';
};
networking = {
enableIPv6 = false;
hostName = "robert";
defaultGateway = {
address = "192.168.1.254";
interface = "wlan0";
};
}
The problem:
The new configuration.nix isn’t loaded at boot, the old configuration persists. I think my problem is similar to this one: ZFS system: non-ZFS filesystems not mounting · Issue #85875 · NixOS/nixpkgs · GitHub. The diference here being that I there exists the firmware partition because the sd image has the boot dir in the root partition, but before running nixos-rebuild boot
I make sure I mount the firmware paritition in step 1. Am I missing something here?
After step 2 nixos-rebuild boot
:
[root@nixos:~]# sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
1 1970-01-01 00:00:13
2 2020-06-23 14:45:46 (current)
After reboot I checked the contents of /run/current-system/configuration.nix
and it is the same config as the one used to create the sd image, so to me it seems that I haven’t booted into the new configuration (I have system.copySystemConfiguration = true;
in both the machine configuration.nix and the sd-image.nix).
Possible solutions and what I need help with
I checked the contents of the raspbian os image and saw that /boot
contains all of the firmware files, in contrast to the sd-image.nix
which has all the firmware files in /boot/firmware
. So what I would like to is overwrite the configuration.fileSystems in nixpkgs/nixos/modules/installer/cd-dvd/sd-image.nix
config = {
fileSystems = {
"/boot/firmware" = {
device = "/dev/disk/by-label/FIRMWARE";
fsType = "vfat";
# Alternatively, this could be removed from the configuration.
# The filesystem is not needed at runtime, it could be treated
# as an opaque blob instead of a discrete FAT32 filesystem.
options = [ "nofail" "noauto" ];
};
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
};
};
....
};
And use this instead in my sd-image.nix:
fileSystems = {
"/boot" = {
device = "/dev/disk/by-label/FIRMWARE";
fsType = "vfat";
};
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
};
};
That way all the firmware files are written to /boot
instead of /boot/firmware
. I just don’t know how to overwrite attributes yet: The option
fileSystems./boot.’ has conflicting definitions…. Maybe this is completely the wrong way to approach this problem because what I'm trying to do is not part f the attributes of
sdImage`.
Thanks for reading!
Edit: I didn’t know that discourse would comment on all the github issues. Sorry for the spam!