From 0f47d72e7af9967991cdc23a80bc5a954522719d Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Mon, 6 Jan 2020 17:09:56 -0500 Subject: [PATCH] Burn u-boot to the image --- configuration.nix | 18 +++- nixos/sd-image-aarch64.nix | 38 ++++++++ nixos/sd-image.nix | 176 +++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 nixos/sd-image-aarch64.nix create mode 100644 nixos/sd-image.nix diff --git a/configuration.nix b/configuration.nix index 4cef15a..8fa06c2 100644 --- a/configuration.nix +++ b/configuration.nix @@ -1,10 +1,14 @@ { config, pkgs, lib, ... }: + +let + uboot = pkgs.uBootPinebookPro; +in { imports = [ - + - + ./nixos/sd-image-aarch64.nix ]; nixpkgs.overlays = [ @@ -12,4 +16,14 @@ ]; boot.kernelPackages = pkgs.linuxPackages_pinebookpro; + + sdImage = { + manipulateImageCommands = '' + (PS4=" $ "; set -x + dd if=${uboot}/idbloader.img of=$img bs=512 seek=64 conv=notrunc + dd if=${uboot}/u-boot.itb of=$img bs=512 seek=16384 conv=notrunc + ) + ''; + compressImage = lib.mkForce false; + }; } diff --git a/nixos/sd-image-aarch64.nix b/nixos/sd-image-aarch64.nix new file mode 100644 index 0000000..34d2837 --- /dev/null +++ b/nixos/sd-image-aarch64.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +let + extlinux-conf-builder = + import { + pkgs = pkgs.buildPackages; + }; +in +{ + imports = [ + ./sd-image.nix + ]; + + boot.loader.grub.enable = false; + boot.loader.generic-extlinux-compatible.enable = true; + + boot.consoleLogLevel = lib.mkDefault 7; + + boot.kernelParams = [ + "cma=32M" + #"console=ttyS0,115200n8" "console=ttyAMA0,115200n8" "console=tty0" + "console=ttyS2,1500000n8" "earlycon=uart8250,mmio32,0xff1a0000" "earlyprintk" + ]; + + boot.initrd.availableKernelModules = [ + ]; + + sdImage = { + populateRootCommands = '' + mkdir -p ./files/boot + ${extlinux-conf-builder} -t 3 -c ${config.system.build.toplevel} -d ./files/boot + ''; + }; + + # the installation media is also the installation target, + # so we don't want to provide the installation configuration.nix. + installer.cloneConfig = false; +} diff --git a/nixos/sd-image.nix b/nixos/sd-image.nix new file mode 100644 index 0000000..32633ca --- /dev/null +++ b/nixos/sd-image.nix @@ -0,0 +1,176 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + rootfsImage = pkgs.callPackage ({ + inherit (config.sdImage) storePaths; + #compressImage = false; + populateImageCommands = config.sdImage.populateRootCommands; + volumeLabel = "NIXOS_SD"; + } // optionalAttrs (config.sdImage.rootPartitionUUID != null) { + uuid = config.sdImage.rootPartitionUUID; + }); +in +{ + options.sdImage = { + imageName = mkOption { + default = "${config.sdImage.imageBaseName}-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}.img"; + description = '' + Name of the generated image file. + ''; + }; + + imageBaseName = mkOption { + default = "nixos-sd-image"; + description = '' + Prefix of the name of the generated image file. + ''; + }; + + 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. + ''; + }; + + rootPartitionUUID = mkOption { + type = types.nullOr types.str; + default = null; + example = "14e19a7b-0ae0-484d-9d54-43bd6fdc20c7"; + description = '' + UUID for the main NixOS partition on the SD card. + ''; + }; + + gapSize = mkOption { + type = types.int; + # This is probably way too much... meh. + default = 30; + internal = true; + description = '' + Gap before the partition, to put u-boot into. + ''; + }; + + populateRootCommands = mkOption { + example = literalExample "''\${extlinux-conf-builder} -t 3 -c \${config.system.build.toplevel} -d ./files/boot''"; + description = '' + Shell commands to populate the ./files directory. + All files in that directory are copied to the + root (/) partition on the SD image. Use this to + populate the ./files/boot (/boot) directory. + ''; + }; + + manipulateImageCommands = mkOption { + default = ":"; + description = '' + Additional manipulations to do to the image. + For example, embedding the right u-boot. + ''; + }; + + compressImage = mkOption { + type = types.bool; + default = true; + description = '' + Whether the SD image should be compressed using + bzip2. + ''; + }; + + }; + + config = { + fileSystems = { + "/" = { + device = "/dev/disk/by-label/NIXOS_SD"; + fsType = "ext4"; + }; + }; + + sdImage.storePaths = [ config.system.build.toplevel ]; + + system.build.sdImage = pkgs.callPackage ({ stdenv, dosfstools, e2fsprogs, + mtools, libfaketime, utillinux, bzip2/*, zstd*/ }: stdenv.mkDerivation { + name = config.sdImage.imageName; + + nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime utillinux bzip2 /*zstd */]; + + inherit (config.sdImage) compressImage; + + buildCommand = '' + mkdir -p $out/nix-support $out/sd-image + export img=$out/sd-image/${config.sdImage.imageName} + + echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system + if test -n "$compressImage"; then + echo "file sd-image $img.bz2" >> $out/nix-support/hydra-build-products + else + echo "file sd-image $img" >> $out/nix-support/hydra-build-products + fi + + #echo "Decompressing rootfs image" + #zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img + cp -v "${rootfsImage}" ./root-fs.img + + # Gap in front of the first partition, in MiB + gap=8 + + # Create the image file sized to fit the gap and /, plus slack. + rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }') + gapSizeBlocks=$((${toString config.sdImage.gapSize} * 1024 * 1024 / 512)) + imageSize=$((rootSizeBlocks * 512 + gapSizeBlocks * 512 + gap * 1024 * 1024)) + truncate -s $imageSize $img + + # type=b is 'W95 FAT32', type=83 is 'Linux'. + # The "bootable" partition is where u-boot will look file for the bootloader + # information (dtbs, extlinux.conf file). + sfdisk $img <