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
159
|
{
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"
'';
usbNetworkConfig = writeText "10-usb.network" ''
[Match]
Name=usb*
[Network]
DHCP=yes
'';
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/mmcblk2p/vda/' fstab
upload fstab /etc/fstab
upload ${ifnameUdevRule} /etc/udev/rules.d/70-persistent-net.rules
upload ${usbNetworkConfig} /etc/systemd/network/10-usb.network
upload ${xochitlService} /lib/systemd/system/xochitl.service
# delete any systemd units that hinder or delay startup
rm /lib/systemd/system/kdump.service
rm /lib/systemd/system/wacom_flash.service
rm /lib/systemd/system/memfaultd.service
rm /lib/systemd/system/swupdate.service
rm /lib/systemd/system/swupdate.socket
rm /etc/systemd/system/multi-user.target.wants/busybox-ifplugd@usb1.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
'';
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
'';
}
|