{
  fetchurl,
  writeText,
  libguestfs-with-appliance,
  pkgsCross,
  qemu,
  runCommand,
  cpio,
  writeShellApplication,
  sshPassword,
  sshPort,
  httpPort,
}:
let
  updateName = "remarkable-production-memfault-image-3.14.1.9-rm2-public";

  updateArchive = fetchurl {
    url =
      # TODO: this is not an official source. might be worth authenticating the updates
      "https://storage.googleapis.com/remarkable-versions/${updateName}.swu";
    hash = "sha256-8zlAGdv+w2KO7BruRQLQC9ivGSHtK82e36ASIeRF3zI=";
  };

  xochitlConfig = writeText "xochitl.conf" ''
    [General]
    DeveloperPassword=${sshPassword}
    wifion=false
    WebInterfaceEnabled=true
    IdleSuspendDelay=0
    SuspendPowerOffDelay=0
  '';

  usbMacAddr = "52:54:00:12:34:56";

  ifnameUdevRule = writeText "70-persistent-net.rules" ''
    SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \
      ATTR{address}=="${usbMacAddr}", \
      ATTR{type}=="1", KERNEL=="eth*", NAME="usb0"
  '';

  usbNetworkConfig = writeText "10-usb.network" ''
    [Match]
    Name=usb*

    [Network]
    DHCP=yes
  '';

  xochitlService = writeText "xochitl.service" ''
    [Unit]
    Description=reMarkable main application
    After=home.mount network.target

    [Service]
    ExecStart=/usr/bin/xochitl --system
    Restart=always
    # required to make xochitl run
    Environment=LD_PRELOAD=/usr/lib/libfakefbdev.so

    [Install]
    WantedBy=multi-user.target
  '';

  fakefbdev = pkgsCross.armv7l-hf-multiplatform.gcc11Stdenv.mkDerivation {
    name = "fakefbdev";
    src = ./fakefbdev;

    installFlags = [ "DESTDIR=${placeholder "out"}" ];
  };

  kernel = pkgsCross.armv7l-hf-multiplatform.linux_5_4;

  rootfsImage = runCommand "rm-rootfs.ext4" { nativeBuildInputs = [ cpio ]; } ''
    cpio -i --file ${updateArchive}
     gzip -dc ${updateName}.ext4.gz > $out
  '';

  diskImage =
    runCommand "rm-disk.qcow2"
      {
        nativeBuildInputs = [
          qemu
          libguestfs-with-appliance
        ];
      }
      ''
        qemu-img create -f qcow2 $out 8G

        guestfish --rw --blocksize=512 --add $out <<EOF
        run

        # not the original partition table of the RM2
        part-init /dev/sda gpt
        part-add /dev/sda p     2048  2099199
        part-add /dev/sda p  2099200 10487807
        part-add /dev/sda p 10487808 12584959
        part-add /dev/sda p 12584960 16775167

        mkfs vfat /dev/sda1
        upload ${rootfsImage} /dev/sda2
        resize2fs /dev/sda2
        # we disable the orphan_file feature to avoid the error
        # '/dev/vda4 has unsupported feature(s): FEATURE_C12'
        # when e2fsck runs at boot
        mkfs ext4 /dev/sda4 features:^orphan_file

        mount /dev/sda2 /

        copy-in ${kernel}/lib/modules /lib

        download /etc/fstab fstab
        ! sed -i 's/mmcblk2p/vda/' fstab
        upload fstab /etc/fstab

        upload ${ifnameUdevRule} /etc/udev/rules.d/70-persistent-net.rules
        upload ${usbNetworkConfig} /etc/systemd/network/10-usb.network

        upload ${xochitlService} /lib/systemd/system/xochitl.service

        # delete any systemd units that hinder or delay startup
        rm /lib/systemd/system/kdump.service
        rm /lib/systemd/system/wacom_flash.service
        rm /lib/systemd/system/memfaultd.service
        rm /lib/systemd/system/swupdate.service
        rm /lib/systemd/system/swupdate.socket
        rm /etc/systemd/system/multi-user.target.wants/busybox-ifplugd@usb1.service

        upload ${fakefbdev}/lib/libfakefbdev.so /usr/lib/libfakefbdev.so
        chmod 0755 /usr/lib/libfakefbdev.so

        mount /dev/sda4 /home
        cp-a /etc/skel /home/root

        mkdir-p /home/root/.local/share/remarkable/xochitl
        mkdir-p /home/root/.config/remarkable
        upload ${xochitlConfig} /home/root/.config/remarkable/xochitl.conf

        EOF
      '';

in
writeShellApplication {
  name = "reMder-server";

  runtimeInputs = [ qemu ];

  text = ''
    rm -f ./reMder.qcow2
    qemu-img create -b ${diskImage} -F qcow2 -f qcow2 ./reMder.qcow2

    qemu-system-aarch64 \
        -machine virt \
        -enable-kvm \
        -cpu host,aarch64=off \
        -m 2048 \
        -kernel ${kernel}/zImage \
        -drive if=none,file=./reMder.qcow2,format=qcow2,id=hd \
        -device virtio-blk-device,drive=hd \
        -netdev user,hostfwd=tcp::${toString sshPort}-:22,hostfwd=tcp::${toString httpPort}-:80,id=net \
        -device virtio-net-device,netdev=net,mac=${usbMacAddr} \
        -append "console=ttyAMA0 rootfstype=ext4 root=/dev/vda2 rw rootwait init=/sbin/init" \
        -serial mon:stdio \
        -nographic
  '';
}