about summary refs log tree commit diff
path: root/server.nix
blob: 31462cda977135c2e5dfc8fe59f6ed56c621c161 (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
{ fetchurl, writeText, libguestfs-with-appliance, pkgsCross, qemu, runCommand
, writeShellApplication, sshPassword, sshPort, httpPort }:
let
  updateName = "remarkable-ct-prototype-image-3.16.1.0-ferrari-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 = "";
  };

  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 # TODO uncomment?

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

  fakefbdev = pkgsCross.remarkable2.gcc11Stdenv.mkDerivation {
    name = "fakefbdev";
    src = ./fakefbdev;

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

  rootfsImage = runCommand "rm-rootfs.ext4" ''
    cpio -i --file ${updateArchive}
    gzip -dc ${updateName}.ext4.verity.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

    part-init /dev/sda mbr
    part-add /dev/sda p 2048    43007
    part-add /dev/sda p 43008   595967
    part-add /dev/sda p 595968  1148927
    part-add /dev/sda p 1148928 14942207

    mkfs vfat /dev/sda1
    upload ${rootfsImage} /dev/sda2
    mkfs ext4 /dev/sda3
    mkfs ext4 /dev/sda4

    mount /dev/sda2 /

    download /etc/fstab fstab
    ! sed -i 's/mmcblk2p/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

    rm /lib/systemd/system/remarkable-fail.service
    rm /lib/systemd/system/rm-sync.service
    upload ${xochitlService} /lib/systemd/system/xochitl.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
  '';

  kernel = pkgsCross.aarch64-linux.linux_5_4;

in writeShellApplication {
  name = "reMder-server";

  runtimeInputs = [ qemu ];

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

    qemu-system-aarch64 \
        -enable-kvm \
        -machine virt \
        -cpu host \
        -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 stdio \
        -monitor none \
        -nographic
  '';
}