Skip to content

Instantly share code, notes, and snippets.

@tilpner
Created January 29, 2019 19:00
Show Gist options
  • Save tilpner/da93457bc73335ebca58559dd8e03c5e to your computer and use it in GitHub Desktop.
Save tilpner/da93457bc73335ebca58559dd8e03c5e to your computer and use it in GitHub Desktop.
system.build = {
sdImage =
let
inherit (pkgs.crossPkgs) stdenv runCommand callPackage pinebook;
rootFS = callPackage (nixosLib /make-ext4-fs.nix) {
storePaths = [ config.system.build.toplevel ];
volumeLabel = "nixos";
};
inherit (pinebook) uboot;
ubootName = "u-boot-sunxi-with-spl.bin";
configTxt = pkgs.writeText "config.txt" ''
kernel=${ubootName}
# Boot in 64-bit mode.
arm_control=0x200
# U-Boot used to need this to work, regardless of whether UART is actually used or not.
# TODO: check when/if this can be removed.
enable_uart=1
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
'';
in stdenv.mkDerivation {
name = "sd-image";
nativeBuildInputs = with pkgs.hostPkgs; [ utillinux e2fsprogs libguestfs ];
buildCommand = ''
mkdir -p $out/nix-support
export img=$out/sd-image
export HOME=$(mktemp -d)
echo "${stdenv.buildPlatform.system}" > $out/nix-support/system
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
# Create the image file sized to fit /boot and /, plus 20M of slack
rootSizeBlocks=$(du -B 512 --apparent-size ${rootFS} | awk '{ print $1 }')
imageSize=$((rootSizeBlocks * 512 + 20 * 1024 * 1024))
truncate -s $imageSize $img
du -sh $img
# type=83 is 'Linux'.
sfdisk $img <<EOF
label: dos
start=8M, type=83, bootable
EOF
# Copy the rootfs into the SD image
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
dd conv=notrunc if=${rootFS} of=$img seek=$START count=$SECTORS
# Populate the files intended for /boot
mkdir boot
cp ${uboot}/${ubootName} boot/
cp ${configTxt} boot/config.txt
${import (nixos /system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix) { pkgs = pkgs.hostPkgs; }} \
-t 3 -c ${config.system.build.toplevel} -d ./boot
guestfish \
add $img : run : mount /dev/sda1 / : \
mkdir /boot : copy-in boot /
du -sh $img
dd conv=notrunc if=${uboot}/${ubootName} of=$img bs=1024 seek=8
'';
};
};
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)
bootDevice=$(lsblk -npo PKNAME $rootPart)
# Resize the root partition and the filesystem to fit the disk
echo ",+," | sfdisk -N1 --no-reread $bootDevice
${pkgs.parted}/bin/partprobe
${pkgs.e2fsprogs}/bin/resize2fs $rootPart
# Register the contents of the initial Nix store
${config.nix.package.out}/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.out}/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
'';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment