diff --git a/flake.nix b/flake.nix index ac631ba..0e14ea5 100644 --- a/flake.nix +++ b/flake.nix @@ -8,6 +8,7 @@ outputs = { self, nixpkgs, not-os }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; + not-os-cfg = not-os-configured.config.system; patched-not-os = pkgs.applyPatches { name = "not-os-patched"; @@ -194,10 +195,10 @@ extraConfig = '' CONFIG_AUTOBOOT=y 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 0x8000000 devicetree.dtb - fatload mmc 0 0xA400000 uramdisk.image.gz + fatload mmc 0 0xA400000 uRamdisk.image.gz bootm 0x6400000 0xA400000 0x8000000 ''}" CONFIG_BOOTDELAY=0 @@ -236,6 +237,99 @@ system = "x86_64-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 { packages.x86_64-linux = { inherit mkbootimage; @@ -244,7 +338,9 @@ zc706-u-boot = u-boot { board = "zc706"; }; zc706-fsbl = fsbl { 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; };