summary refs log tree commit diff
path: root/nixos/modules/installer
diff options
context:
space:
mode:
authorviric <viric@viric.name>2015-07-29 14:13:57 +0200
committerviric <viric@viric.name>2015-07-29 14:13:57 +0200
commit982ce5ed589987bff22019e19f6feddf3609cb58 (patch)
tree67e1f8b286b3a0069de78dd58ca2651297a30e2d /nixos/modules/installer
parentf5954509122160ed8209a3158e49ae054c12fcf8 (diff)
parentdf86813d9727aa3a9e3dcc45347f97b71bd01599 (diff)
downloadnixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar.gz
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar.bz2
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar.lz
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar.xz
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.tar.zst
nixpkgs-982ce5ed589987bff22019e19f6feddf3609cb58.zip
Merge pull request #8978 from dezgeg/pr-arm-images
ARM SD card image expressions
Diffstat (limited to 'nixos/modules/installer')
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix40
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix46
-rw-r--r--nixos/modules/installer/cd-dvd/sd-image.nix127
3 files changed, 213 insertions, 0 deletions
diff --git a/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
new file mode 100644
index 00000000000..0ca57a4635f
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image-armv7l-multiplatform.nix
@@ -0,0 +1,40 @@
+{ config, lib, pkgs, ... }:
+
+let
+  extlinux-conf-builder =
+    import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
+      inherit pkgs;
+    };
+in
+{
+  imports = [
+    ../../profiles/minimal.nix
+    ../../profiles/installation-device.nix
+    ./sd-image.nix
+  ];
+
+  assertions = lib.singleton {
+    assertion = pkgs.stdenv.system == "armv7l-linux";
+    message = "sd-image-armv7l-multiplatform.nix can be only built natively on ARMv7; " +
+      "it cannot be cross compiled";
+  };
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  # FIXME: change this to linuxPackages_latest once v4.2 is out
+  boot.kernelPackages = pkgs.linuxPackages_testing;
+  boot.kernelParams = ["console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0"];
+
+  # FIXME: fix manual evaluation on ARM
+  services.nixosManual.enable = lib.mkOverride 0 false;
+
+  # FIXME: this probably should be in installation-device.nix
+  users.extraUsers.root.initialHashedPassword = "";
+
+  sdImage = {
+    populateBootCommands = ''
+        ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
+    '';
+  };
+}
diff --git a/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
new file mode 100644
index 00000000000..199a252ad2b
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image-raspberrypi.nix
@@ -0,0 +1,46 @@
+{ config, lib, pkgs, ... }:
+
+let
+  extlinux-conf-builder =
+    import ../../system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix {
+      inherit pkgs;
+    };
+in
+{
+  imports = [
+    ../../profiles/minimal.nix
+    ../../profiles/installation-device.nix
+    ./sd-image.nix
+  ];
+
+  assertions = lib.singleton {
+    assertion = pkgs.stdenv.system == "armv6l-linux";
+    message = "sd-image-raspberrypi.nix can be only built natively on ARMv6; " +
+      "it cannot be cross compiled";
+  };
+
+  # Needed by RPi firmware
+  nixpkgs.config.allowUnfree = true;
+
+  boot.loader.grub.enable = false;
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  boot.kernelPackages = pkgs.linuxPackages_rpi;
+
+  # FIXME: fix manual evaluation on ARM
+  services.nixosManual.enable = lib.mkOverride 0 false;
+
+  # FIXME: this probably should be in installation-device.nix
+  users.extraUsers.root.initialHashedPassword = "";
+
+  sdImage = {
+    populateBootCommands = ''
+      for f in bootcode.bin fixup.dat start.elf; do
+        cp ${pkgs.raspberrypifw}/share/raspberrypi/boot/$f boot/
+      done
+      cp ${pkgs.ubootRaspberryPi}/u-boot.bin boot/u-boot-rpi.bin
+      echo 'kernel u-boot-rpi.bin' > boot/config.txt
+      ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./boot
+    '';
+  };
+}
diff --git a/nixos/modules/installer/cd-dvd/sd-image.nix b/nixos/modules/installer/cd-dvd/sd-image.nix
new file mode 100644
index 00000000000..12b4f304561
--- /dev/null
+++ b/nixos/modules/installer/cd-dvd/sd-image.nix
@@ -0,0 +1,127 @@
+# This module creates a bootable SD card image containing the given NixOS
+# configuration. The generated image is MBR partitioned, with a FAT /boot
+# partition, and ext4 root partition. The generated image is sized to fit
+# its contents, and a boot script automatically resizes the root partition
+# to fit the device on the first boot.
+#
+# The derivation for the SD image will be placed in
+# config.system.build.sdImage
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  rootfsImage = import ../../../lib/make-ext4-fs.nix {
+    inherit pkgs;
+    inherit (config.sdImage) storePaths;
+    volumeLabel = "NIXOS_SD";
+  };
+in
+{
+  options.sdImage = {
+    storePaths = mkOption {
+      type = with types; listOf package;
+      example = literalExample "[ pkgs.stdenv ]";
+      description = ''
+        Derivations to be included in the Nix store in the generated SD image.
+      '';
+    };
+
+    bootSize = mkOption {
+      type = types.int;
+      default = 128;
+      description = ''
+        Size of the /boot partition, in megabytes.
+      '';
+    };
+
+    populateBootCommands = mkOption {
+      example = literalExample "'' cp \${pkgs.myBootLoader}/u-boot.bin boot/ ''";
+      description = ''
+        Shell commands to populate the ./boot directory.
+        All files in that directory are copied to the
+        /boot partition on the SD image.
+      '';
+    };
+  };
+
+  config = {
+    fileSystems = {
+      "/boot" = {
+        device = "/dev/disk/by-label/NIXOS_BOOT";
+        fsType = "vfat";
+      };
+      "/" = {
+        device = "/dev/disk/by-label/NIXOS_SD";
+        fsType = "ext4";
+      };
+    };
+
+    sdImage.storePaths = [ config.system.build.toplevel ];
+
+    system.build.sdImage = pkgs.stdenv.mkDerivation {
+      name = "sd-image-${pkgs.stdenv.system}.img";
+
+      buildInputs = with pkgs; [ dosfstools e2fsprogs mtools libfaketime utillinux ];
+
+      buildCommand = ''
+        # Create the image file sized to fit /boot and /, plus 4M of slack
+        rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
+        bootSizeBlocks=$((${toString config.sdImage.bootSize} * 1024 * 1024 / 512))
+        imageSize=$((rootSizeBlocks * 512 + bootSizeBlocks * 512 + 4096 * 1024))
+        truncate -s $imageSize $out
+
+        # type=b is 'W95 FAT32', type=83 is 'Linux'.
+        sfdisk $out <<EOF
+            label: dos
+            label-id: 0x2178694e
+
+            start=1M, size=$bootSizeBlocks, type=b, bootable
+            type=83
+        EOF
+
+        # Copy the rootfs into the SD image
+        eval $(partx $out -o START,SECTORS --nr 2 --pairs)
+        dd conv=notrunc if=${rootfsImage} of=$out seek=$START count=$SECTORS
+
+        # Create a FAT32 /boot partition of suitable size into bootpart.img
+        eval $(partx $out -o START,SECTORS --nr 1 --pairs)
+        truncate -s $((SECTORS * 512)) bootpart.img
+        faketime "1970-01-01 00:00:00" mkfs.vfat -i 0x2178694e -n NIXOS_BOOT bootpart.img
+
+        # Populate the files intended for /boot
+        mkdir boot
+        ${config.sdImage.populateBootCommands}
+
+        # Copy the populated /boot into the SD image
+        (cd boot; mcopy -bpsvm -i ../bootpart.img ./* ::)
+        dd conv=notrunc if=bootpart.img of=$out seek=$START count=$SECTORS
+      '';
+    };
+
+    boot.postBootCommands = ''
+      # On the first boot do some maintenance tasks
+      if [ -f /nix-path-registration ]; then
+        # Figure out device names for the boot device and root filesystem.
+        rootPart=$(readlink -f /dev/disk/by-label/NIXOS_SD)
+        bootDevice=$(lsblk -npo PKNAME $rootPart)
+
+        # Resize the root partition and the filesystem to fit the disk
+        echo ",+," | sfdisk -N2 --no-reread $bootDevice
+        ${pkgs.parted}/bin/partprobe
+        ${pkgs.e2fsprogs}/bin/resize2fs $rootPart
+
+        # Register the contents of the initial Nix store
+        ${config.nix.package}/bin/nix-store --load-db < /nix-path-registration
+
+        # nixos-rebuild also requires a "system" profile and an /etc/NIXOS tag.
+        touch /etc/NIXOS
+        ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
+
+        # Prevents this from running on later boots.
+        rm -f /nix-path-registration
+      fi
+    '';
+  };
+}