diff options
| author | Malte Voos <git@mal.tc> | 2026-05-27 17:30:32 +0900 |
|---|---|---|
| committer | Malte Voos <git@mal.tc> | 2026-05-28 13:08:20 +0900 |
| commit | 64c1fd77c5d8d99607a00b151a71a1fee2d1b0c3 (patch) | |
| tree | d30559370b64753b101f052f56f360b162b0642b | |
| parent | a5b1a5a6a22ddd4b30de59cfcb965cc918a6485a (diff) | |
| download | reMder-main.tar.gz reMder-main.zip | |
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | README.md | 23 | ||||
| -rw-r--r-- | client.nix | 5 | ||||
| -rw-r--r-- | flake.nix | 62 | ||||
| -rw-r--r-- | foo.pdf | bin | 131413 -> 0 bytes | |||
| -rw-r--r-- | foo.rmdoc | bin | 452882 -> 0 bytes | |||
| -rw-r--r-- | server.nix | 138 |
7 files changed, 80 insertions, 150 deletions
@@ -1,2 +1,2 @@ result -reMder.qcow2 +foo.* @@ -6,35 +6,30 @@ interface's PDF rendering functionality to render your documents. As a result, it should be able to render any reMarkable document, in particular those created on newer firmware versions. -Currently, reMder uses firmware version v3.20.0.92. +Currently, reMder uses firmware version v3.27.1.0. ## Building -Use the nixpkgs overlay provided by the flake. You need a nixpkgs that has -https://github.com/NixOS/nixpkgs/pull/381224 merged. - -TODO expand instructions for non-Nix users - -Moreover, at the moment reMder runs only on 64-bit ARM processors that can -execute 32-bit ARM instructions (e.g. the Cortex-A72 found on the Raspberry -Pi 4B.) I'll add support for more platforms when I find the time. +``` +$ nix build +``` ## Usage First, run ``` -$ reMder-server & +$ result/bin/reMder-server & ``` -This will boot up an emulated reMarkable in QEMU, with its disk image at -./reMder.qcow2. The reMarkable's SSH server will be accessible on the host at -localhost:43922 and the USB web inteface at localhost:43980. +This will boot up an emulated reMarkable in QEMU. The reMarkable's SSH server +will be accessible on the host at localhost:43922 and the USB web inteface at +localhost:43980. After reMder-server has initialized, use ``` -$ reMder-client test.(rmdoc/zip) test.pdf +$ result/bin/reMder-client test.(rmdoc/zip) test.pdf ``` to render documents to PDF. @@ -2,9 +2,7 @@ writeShellApplication, curl, openssh, - sshpass, rsync, - sshPassword, sshPort, httpPort, }: @@ -15,13 +13,12 @@ writeShellApplication { runtimeInputs = [ curl openssh - sshpass rsync ]; text = let - ssh = "sshpass -p ${sshPassword} ssh -q -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p ${toString sshPort}"; + ssh = "ssh -q -F none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p ${toString sshPort}"; guest = "root@127.0.0.1"; documentDir = "/home/root/.local/share/remarkable/xochitl"; baseUrl = "http://127.0.0.1:${toString httpPort}"; @@ -9,44 +9,32 @@ nixpkgs, flake-utils, }: - let - overlay = - final: prev: - let - sshPassword = "1234"; - sshPort = 43922; - httpPort = 43980; + flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ] ( + system: + let + pkgs = import nixpkgs { + inherit system; + overlays = nixpkgs.lib.optional (system == "aarch64-linux") (import ./overlay.nix); + }; - server = final.callPackage ./server.nix { - inherit sshPassword sshPort httpPort; - }; - client = final.callPackage ./client.nix { - inherit sshPassword sshPort httpPort; - }; + sshPort = 43922; + httpPort = 43980; - reMder = final.symlinkJoin { - name = "reMder"; - paths = [ - client - server - ]; - }; - in - { - inherit reMder; + server = pkgs.callPackage ./server.nix { + inherit sshPort httpPort; + }; + client = pkgs.callPackage ./client.nix { + inherit sshPort httpPort; + }; + in + { + packages.default = pkgs.symlinkJoin { + name = "reMder"; + paths = [ + client + server + ]; }; - in - flake-utils.lib.eachDefaultSystem (system: { - packages.default = - let - pkgs = import nixpkgs { - inherit system; - overlays = [ (import ./overlay.nix) overlay ]; - }; - in - pkgs.reMder; - }) - // { - overlays.default = overlay; - }; + } + ); } diff --git a/foo.pdf b/foo.pdf Binary files differdeleted file mode 100644 index 8cdd5f4..0000000 --- a/foo.pdf +++ /dev/null diff --git a/foo.rmdoc b/foo.rmdoc Binary files differdeleted file mode 100644 index 7a2d8f4..0000000 --- a/foo.rmdoc +++ /dev/null @@ -7,7 +7,6 @@ runCommand, cpio, writeShellApplication, - sshPassword, sshPort, httpPort, writeScript, @@ -24,89 +23,60 @@ let xochitlConfig = writeText "xochitl.conf" '' [General] - DeveloperPassword=${sshPassword} AirplaneMode=true WebInterfaceEnabled=true IdleSuspendDelay=0 SuspendPowerOffDelay=0 ''; - usbMacAddr = "52:54:00:12:34:56"; + fakefbdev = pkgsCross.armv7l-hf-multiplatform.stdenv.mkDerivation { + name = "fakefbdev"; + src = ./fakefbdev; - ifnameUdevRule = writeText "70-persistent-net.rules" '' - SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", \ - ATTR{address}=="${usbMacAddr}", \ - ATTR{type}=="1", KERNEL=="eth*", NAME="usb0" - ''; + installFlags = [ "DESTDIR=${placeholder "out"}" ]; + }; + + kernel = pkgsCross.armv7l-hf-multiplatform.linux; - mmcSymlinkUdevRule = writeText "" '' - ACTION=="add", KERNEL=="vda", SYMLINK+="mmcblk2" - ACTION=="add", KERNEL=="vda[0-9]", SYMLINK+="mmcblk2p%n" + rootfsImage = runCommand "rm-rootfs.ext4" { nativeBuildInputs = [ cpio ]; } '' + cpio -i --file ${updateArchive} + gzip -dc ${updateName}.ext4.gz > $out ''; - usbNetworkConfig = writeText "10-usb.network" '' - [Match] - Name=usb* + initScript = writeScript "init" '' + #!/bin/sh + set -e - [Network] - DHCP=yes - ''; + mount -t proc proc /proc + mount -t sysfs sysfs /sys + mkdir -p /dev/pts && mount -t devpts devpts /dev/pts + mkdir -p /dev/shm && mount -t tmpfs shm /dev/shm -o mode=1777 + mkdir -p /run && mount -t tmpfs tmpfs /run -o mode=0755 + mkdir -p /tmp && mount -t tmpfs tmpfs /tmp -o mode=1777 - usbWaitOnlineService = writeText "usb0-wait-online.service" '' - [Unit] - Description=Wait for usb0 to be routable - Before=network-online.target + for i in 1 2 3 4; do + ln -s /dev/vda$i /dev/mmcblk2p$i + done - [Service] - Type=oneshot - ExecStart=/bin/sh -c 'until ip -4 addr show usb0 | grep -q "inet "; do sleep 1; done' - RemainAfterExit=yes + [ ! -s /etc/machine-id ] && dbus-uuidgen > /etc/machine-id + mkdir -p /run/dbus + dbus-daemon --system --fork - [Install] - WantedBy=network-online.target - ''; + ip link set lo up + ip link set eth0 name usb0 + ip link set usb0 up + udhcpc -i usb0 - xochitlService = writeText "xochitl.service" '' - [Unit] - Description=reMarkable main application - DefaultDependencies=no - Conflicts=shutdown.target - Before=shutdown.target - # add network-online.target to the original dependencies so that xochitl - # can bind to the usb0 interface when it starts - Wants=rm-sync.service network-online.target - After=var-lib-uboot.mount dbus.socket network-online.target - Requires=dbus.socket - - [Service] - ExecStart=/usr/bin/xochitl --system - Restart=on-failure - NotifyAccess=all - # required to make xochitl run - Environment=LD_PRELOAD=/usr/lib/libfakefbdev.so - - [Install] - WantedBy=multi-user.target - ''; - - fakefbdev = pkgsCross.armv7l-hf-multiplatform.stdenv.mkDerivation { - name = "fakefbdev"; - src = ./fakefbdev; + dropbear -REB - installFlags = [ "DESTDIR=${placeholder "out"}" ]; - }; + export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin + LD_PRELOAD=/usr/lib/libfakefbdev.so exec xochitl --system + ''; doNothing = writeScript "do-nothing" '' #!/bin/sh ''; - kernel = pkgsCross.armv7l-hf-multiplatform.linux; - - rootfsImage = runCommand "rm-rootfs.ext4" { nativeBuildInputs = [ cpio ]; } '' - cpio -i --file ${updateArchive} - gzip -dc ${updateName}.ext4.gz > $out - ''; - diskImage = runCommand "rm-disk.qcow2" { @@ -131,43 +101,22 @@ let mkfs vfat /dev/sda1 upload ${rootfsImage} /dev/sda2 resize2fs /dev/sda2 - # we disable the orphan_file feature to avoid the error - # 'unsupported feature(s): FEATURE_C12' when e2fsck runs at boot - mkfs ext4 /dev/sda4 features:^orphan_file + mkfs ext4 /dev/sda4 mount /dev/sda2 / - download /etc/fstab fstab - ! sed -i /unknown/d fstab - upload fstab /etc/fstab - copy-in ${kernel.modules}/lib/modules /usr/lib - upload ${ifnameUdevRule} /etc/udev/rules.d/70-persistent-net.rules - upload ${mmcSymlinkUdevRule} /etc/udev/rules.d/70-mmc-symlinks.rules - upload ${usbNetworkConfig} /etc/systemd/network/10-usb.network - upload ${xochitlService} /usr/lib/systemd/system/xochitl.service - - upload ${usbWaitOnlineService} /etc/systemd/system/usb0-wait-online.service - mkdir-p /etc/systemd/system/network-online.target.wants - ln-s /etc/systemd/system/usb0-wait-online.service /etc/systemd/system/network-online.target.wants/usb0-wait-online.service - - # delete any systemd units that hinder or delay startup - rm /usr/lib/systemd/system/wacom_flash.service - rm /usr/lib/systemd/system/memfaultd.service - rm /usr/lib/systemd/system/memfault-attributes.service - rm /usr/lib/systemd/system/swupdate.service - rm /usr/lib/systemd/system/swupdate.socket - rm /usr/lib/systemd/system/system-hardening.service - rm /usr/lib/systemd/system/wpa_supplicant.service - - # stub the usb-ether-once script - upload ${doNothing} /usr/sbin/usb-ether-once - chmod 0755 /usr/sbin/usb-ether-once + upload ${initScript} /sbin/init + chmod 0755 /sbin/init upload ${fakefbdev}/lib/libfakefbdev.so /usr/lib/libfakefbdev.so chmod 0755 /usr/lib/libfakefbdev.so + # prevent xochitl from changing root password + upload ${doNothing} /usr/sbin/usermod + chmod 0755 /usr/sbin/usermod + mount /dev/sda4 /home cp-a /etc/skel /home/root @@ -188,14 +137,15 @@ writeShellApplication { rm -f ./reMder.qcow2 qemu-img create -b ${diskImage} -F qcow2 -f qcow2 ./reMder.qcow2 - qemu-system-aarch64 \ + qemu-system-arm \ -machine virt \ -m 2048 \ -kernel ${kernel}/zImage \ - -drive if=none,file=./reMder.qcow2,format=qcow2,id=hd \ + -snapshot \ + -drive if=none,file=${diskImage},format=qcow2,id=hd \ -device virtio-blk-device,drive=hd \ -netdev user,net=10.11.99.0/27,host=10.11.99.2,dhcpstart=10.11.99.1,hostfwd=tcp::${toString sshPort}-:22,hostfwd=tcp::${toString httpPort}-:80,id=net \ - -device virtio-net-device,netdev=net,mac=${usbMacAddr} \ + -device virtio-net-device,netdev=net \ -append "console=ttyAMA0 rootfstype=ext4 root=/dev/vda2 rw rootwait init=/sbin/init" \ -serial mon:stdio \ -nographic |