diff options
Diffstat (limited to 'nixos/modules/installer/cd-dvd')
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 000000000000..0ca57a4635f4 --- /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 000000000000..199a252ad2b5 --- /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 000000000000..12b4f3045614 --- /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 + ''; + }; +} |