flake: add not-os disk image builder and qemu

This commit is contained in:
Florian Agbuya 2023-12-15 15:34:41 +08:00
parent 543a8632c6
commit 1aee5344a5

102
flake.nix
View File

@ -8,6 +8,7 @@
outputs = { self, nixpkgs, not-os }: outputs = { self, nixpkgs, not-os }:
let let
pkgs = import nixpkgs { system = "x86_64-linux"; }; pkgs = import nixpkgs { system = "x86_64-linux"; };
not-os-cfg = not-os-configured.config.system;
patched-not-os = pkgs.applyPatches { patched-not-os = pkgs.applyPatches {
name = "not-os-patched"; name = "not-os-patched";
@ -194,10 +195,10 @@
extraConfig = '' extraConfig = ''
CONFIG_AUTOBOOT=y CONFIG_AUTOBOOT=y
CONFIG_BOOTCOMMAND="${builtins.replaceStrings [ "\n" ] [ "; " ] '' CONFIG_BOOTCOMMAND="${builtins.replaceStrings [ "\n" ] [ "; " ] ''
setenv bootargs 'root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-configured.config.system.build.toplevel}' setenv bootargs 'root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-cfg.build.toplevel}'
fatload mmc 0 0x6400000 uImage fatload mmc 0 0x6400000 uImage
fatload mmc 0 0x8000000 devicetree.dtb fatload mmc 0 0x8000000 devicetree.dtb
fatload mmc 0 0xA400000 uramdisk.image.gz fatload mmc 0 0xA400000 uRamdisk.image.gz
bootm 0x6400000 0xA400000 0x8000000 bootm 0x6400000 0xA400000 0x8000000
''}" ''}"
CONFIG_BOOTDELAY=0 CONFIG_BOOTDELAY=0
@ -236,6 +237,99 @@
system = "x86_64-linux"; system = "x86_64-linux";
crossSystem.system = "armv7l-linux"; crossSystem.system = "armv7l-linux";
}); });
not-os-qemu = { board ? "zc706" }: let
qemuScript = ''
#!/bin/bash
export PATH=${pkgs.qemu}/bin:$PATH
IMGDIR=$(mktemp -d /tmp/not-os-qemu-XXXXXX)
BASE=$(realpath $(dirname $0))
qemu-img create -F raw -f qcow2 -b $BASE/sd-image.img $IMGDIR/sd-overlay.qcow2 512M
# Some command arguments are based from samples in Xilinx QEMU User Documentation
# See: https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/821854273/Running+Bare+Metal+Applications+on+QEMU
qemu-system-arm \
-M xilinx-zynq-a9 \
-serial /dev/null \
-serial stdio \
-display none \
-dtb $BASE/devicetree.dtb \
-kernel $BASE/uImage \
-initrd $BASE/uRamdisk.image.gz \
-drive file=$IMGDIR/sd-overlay.qcow2,if=sd,format=qcow2 \
-append "root=/dev/mmcblk0p2 console=ttyPS0,115200n8 systemConfig=${builtins.unsafeDiscardStringContext not-os-cfg.build.toplevel}";
rm -rf $IMGDIR
'';
in pkgs.runCommand "not-os-qemu" {
inherit qemuScript;
passAsFile = [ "qemuScript" ];
preferLocalBuild = true;
}
''
mkdir $out
cd $out
cp -s ${not-os-cfg.build.kernel}/uImage .
cp -s ${not-os-cfg.build.uRamdisk}/initrd uRamdisk.image.gz
cp -s ${not-os-cfg.build.kernel}/dtbs/zynq-zc706.dtb devicetree.dtb
cp -s ${sd-image { inherit board; }}/sd-image/sd-image.img .
ln -sv ${not-os-cfg.build.toplevel} toplevel
cp $qemuScriptPath qemu-script
chmod +x qemu-script
patchShebangs qemu-script
'';
sd-image = { board ? "zc706" }: let
rootfsImage = pkgs.callPackage (pkgs.path + "/nixos/lib/make-ext4-fs.nix") {
storePaths = [ not-os-cfg.build.toplevel ];
volumeLabel = "ROOT";
};
# Current firmware (kernel, bootimage, etc..) takes ~18MB
firmwareSize = 30;
firmwarePartitionOffset = 8;
in pkgs.stdenv.mkDerivation {
name = "sd-image";
nativeBuildInputs = with pkgs; [ dosfstools mtools libfaketime util-linux parted ];
buildCommand = ''
mkdir -p $out/nix-support $out/sd-image
export img=$out/sd-image/sd-image.img
echo "${pkgs.stdenv.buildPlatform.system}" > $out/nix-support/system
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
gap=${toString firmwarePartitionOffset}
rootSizeBlocks=$(du -B 512 --apparent-size ${rootfsImage} | awk '{ print $1 }')
firmwareSizeBlocks=$((${toString firmwareSize} * 1024 * 1024 / 512))
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
truncate -s $imageSize $img
fat32Start="$((gap))MB"
fat32End="$((gap + ${toString firmwareSize}))MB"
parted $img mklabel msdos
parted $img mkpart primary fat32 $fat32Start $fat32End
parted $img mkpart primary ext4 $fat32End 100%
parted $img set 1 boot on
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
dd conv=notrunc if=${rootfsImage} of=$img seek=$START count=$SECTORS
eval $(partx $img -o START,SECTORS --nr 1 --pairs)
truncate -s $((SECTORS * 512)) firmware_part.img
faketime "1970-01-01 00:00:00" mkfs.vfat -n BOOT firmware_part.img
mkdir firmware
cp ${bootimage { inherit board; }}/boot.bin firmware/
cp ${not-os-cfg.build.kernel}/uImage firmware/
cp ${not-os-cfg.build.uRamdisk}/initrd firmware/uRamdisk.image.gz
cp ${not-os-cfg.build.kernel}/dtbs/zynq-zc706.dtb firmware/devicetree.dtb
(cd firmware; mcopy -psvm -i ../firmware_part.img ./* ::)
dd conv=notrunc if=firmware_part.img of=$img seek=$START count=$SECTORS
'';
};
in rec { in rec {
packages.x86_64-linux = { packages.x86_64-linux = {
inherit mkbootimage; inherit mkbootimage;
@ -244,7 +338,9 @@
zc706-u-boot = u-boot { board = "zc706"; }; zc706-u-boot = u-boot { board = "zc706"; };
zc706-fsbl = fsbl { board = "zc706"; }; zc706-fsbl = fsbl { board = "zc706"; };
zc706-bootimage = bootimage { board = "zc706"; }; zc706-bootimage = bootimage { board = "zc706"; };
zc706-not-os = not-os-configured.config.system.build.zynq_image; zc706-qemu = not-os-qemu { board = "zc706"; };
zc706-sd-image = sd-image { board = "zc706"; };
zc706-not-os = not-os-cfg.build.zynq_image;
}; };
hydraJobs = packages.x86_64-linux // packages.armv7l-linux; hydraJobs = packages.x86_64-linux // packages.armv7l-linux;
}; };