about summary refs log tree commit diff
path: root/server.nix
blob: 906e2c6488fd1830be51d873ef8c56d6f6805f0a (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
154
155
156
157
158
{ lib, fetchurl, writeText, libguestfs-with-appliance, pkgsCross, qemu
, runCommand, cpio, 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 = "sha256-cwx2qcvxZBX0wAprYKls8P+gthwJJQTceVIO+qdPm/w=";
  };

  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.aarch64-multiplatform.gcc11Stdenv.mkDerivation {
    name = "fakefbdev";
    src = ./fakefbdev;

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

  kernel = pkgsCross.aarch64-multiplatform.linux;

  rootfsImage = runCommand "rm-rootfs.ext4" { nativeBuildInputs = [ cpio ]; } ''
    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

    # not the original partition table of the RMPP
    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 ext4 /dev/sda1
    upload ${rootfsImage} /dev/sda2
    resize2fs /dev/sda2
    mkswap /dev/sda3
    mkfs ext4 /dev/sda4

    mount /dev/sda2 /

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

    download /etc/fstab fstab
    ! sed -i 's#mmcblk0p1#vda1#' fstab
    ! sed -i 's#/dev/mapper/home-encrypted-disk#/dev/vda4#' fstab
    upload fstab /etc/fstab

    download /etc/passwd passwd
    ! sed -i 's#/usr/sbin/rmdevlogin#/bin/sh#' passwd
    upload passwd /etc/passwd

    download /etc/shadow shadow
    ! sed -i 's/root:!:/root::/' shadow
    upload shadow /etc/shadow

    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 \
        -enable-kvm \
        -machine virt \
        -cpu host \
        -m 2048 \
        -kernel ${kernel}/Image \
        -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
  '';
}