aboutsummaryrefslogtreecommitdiff
path: root/server.nix
blob: 78f9e2941f558f7f47c5cccad6cc852b12f164e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
{
  fetchurl,
  writeText,
  libguestfs-with-appliance-nix,
  pkgsCross,
  qemu,
  runCommand,
  cpio,
  writeShellApplication,
  sshPort,
  httpPort,
  writeScript,
}:
let
  updateName = "remarkable-production-image-3.27.1.0-rm2-public";

  updateArchive = fetchurl {
    url =
      # TODO: this is not an official source. might be worth authenticating the updates
      "https://remarkable-software.s3.us-east-2.amazonaws.com/${updateName}.swu";
    hash = "sha256-QPS2n/S1RqkXe0Tg8bAODnvcG5aUOYsAtPvKYwEYGsI=";
  };

  xochitlConfig = writeText "xochitl.conf" ''
    [General]
    AirplaneMode=true
    WebInterfaceEnabled=true
    IdleSuspendDelay=0
    SuspendPowerOffDelay=0
  '';

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

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

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

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

  initScript = writeScript "init" ''
    #!/bin/sh
    set -e

    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

    for i in 1 2 3 4; do
      ln -s /dev/vda$i /dev/mmcblk2p$i
    done

    [ ! -s /etc/machine-id ] && dbus-uuidgen > /etc/machine-id
    mkdir -p /run/dbus
    dbus-daemon --system --fork

    ip link set lo up
    ip link set eth0 name usb0
    ip link set usb0 up
    udhcpc -i usb0

    dropbear -REB

    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
  '';

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

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

        # not the original partition table of the RM2, sizes differ
        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
        mkfs ext4 /dev/sda4

        mount /dev/sda2 /

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

        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

        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-arm \
        -machine virt \
        -m 2048 \
        -kernel ${kernel}/zImage \
        -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 \
        -append "console=ttyAMA0 rootfstype=ext4 root=/dev/vda2 rw rootwait init=/sbin/init" \
        -serial mon:stdio \
        -nographic
  '';
}