about summary refs log tree commit diff
path: root/server.nix
blob: b0d4e6167b9d03c06ac450c282c4f3de49d4b3ce (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
{ 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"
  '';

  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
    mkfs ext4 /dev/sda4

    mount /dev/sda2 /

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

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

    upload ${ifnameUdevRule} /etc/udev/rules.d/70-persistent-net.rules

    # download /lib/systemd/system/dhcpcd.service dhcpcd.service
    # ! sed -i 's/wlan/usb/' dhcpcd.service
    # upload dhcpcd.service /lib/systemd/system/dhcpcd.service TODO

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

    # delete stuff which hinders boot
    # rm /lib/systemd/system/rm-sync.service
    rm /lib/systemd/system/xochitl.service.d/xochitl-service-override.conf
    # rm /lib/systemd/system/wpa_supplicant.service
    # rm /lib/systemd/system/dropbear-wlan.socket
    # rm /lib/systemd/system/keystore.service
    # rm /lib/systemd/system/swapcryptor.service
    # rm /lib/systemd/system/homecryptor.service
    # rm /lib/systemd/system/growpart-home.service
    # rm /lib/systemd/system/memfault-attributes.service
    # rm /lib/systemd/system/swupdate.service
    # rm /lib/systemd/system/swupdate.socket
    # rm /lib/systemd/system/usb-ether-once.service
    # rm /lib/systemd/system/marker-manager.service
    # rm /lib/systemd/system/rm-sanity.timer

    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 = ''
    qemu-img create -b ${diskImage} -F qcow2 -f qcow2 ./reMder.qcow2

    qemu-system-aarch64 \
        -machine virt \
        -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
  '';
}