Compile the executable:
GOOS=linux GOARCH=arm GOARM=7 go build -o test.arm
Send it to the remarkable
Execute it:
reMarkable: ~/ ./test.arm /proc/$(pidof xochitl)/mem
Those informations are a collection of the elements from issue #28 of the reStream project
Remarkable version
reMarkable: ~/ cat /usr/share/remarkable/update.conf
[General]
#REMARKABLE_RELEASE_APPID={98DA7DF2-4E3E-4744-9DE6-EC931886ABAB}
#SERVER=https://get-updates.cloud.remarkable.engineering/service/update2
#GROUP=Prod
#PLATFORM=reMarkable2
REMARKABLE_RELEASE_VERSION=2.5.0.27
Locating the global framebuffer
reMarkable: ~/ strace xochitl
...
563 openat(AT_FDCWD, "/dev/fb0", O_RDWR) = 5
564 ioctl(5, FBIOGET_FSCREENINFO, 0x7ee9d5f4) = 0
565 ioctl(5, FBIOGET_VSCREENINFO, 0x42f0ec) = 0
566 ioctl(5, FBIOPUT_VSCREENINFO, 0x42f0ec) = 0
Global framebuffer is located at 0x42f0ec-4
=0x42f0e8
(4387048
in decimal)
Now get a picture:
#!/bin/sh
pid=`pidof xochitl`
addr=`dd if=/proc/$pid/mem bs=1 count=4 skip=4387048 2>/dev/null | hexdump | awk '{print $3$2}'`
skipbytes=`printf "%d" $((16#$addr))`
dd if=/proc/$pid/mem bs=1 count=2628288 skip=$skipbytes > out.data
Note: 2628288 = 1404*1872 (the number of pixel in the screen of the remarkable)
Get the picture back on my laptop and convert it:
convert -depth 8 -size 1872x1404+0 gray:out.data out.png
package main | |
import ( | |
"encoding/binary" | |
"image" | |
"image/png" | |
"io" | |
"log" | |
"os" | |
) | |
const ( | |
screenWidth = 1872 | |
screenHeight = 1404 | |
fbAddress = 4387048 | |
) | |
func main() { | |
file, err := os.OpenFile(os.Args[1], os.O_RDONLY, os.ModeDevice) | |
if err != nil { | |
log.Fatal("cannot open file: ", err) | |
} | |
defer file.Close() | |
addr, err := getPointer(file, fbAddress) | |
if err != nil { | |
log.Fatal(err) | |
} | |
log.Println("Address is: ", addr) | |
img, err := getImage(file, addr) | |
f, err := os.Create("image.png") | |
if err != nil { | |
log.Fatal(err) | |
} | |
if err := png.Encode(f, img); err != nil { | |
f.Close() | |
log.Fatal(err) | |
} | |
if err := f.Close(); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func getPointer(r io.ReaderAt, offset int64) (int64, error) { | |
pointer := make([]byte, 4) | |
_, err := r.ReadAt(pointer, offset) | |
if err != nil { | |
return 0, err | |
} | |
return int64(binary.LittleEndian.Uint32(pointer)), nil | |
} | |
func getImage(r io.ReaderAt, offset int64) (image.Image, error) { | |
pixels := make([]byte, screenHeight*screenWidth) | |
_, err := r.ReadAt(pixels, offset) | |
if err != nil { | |
return nil, err | |
} | |
img := &image.Gray{ | |
Pix: pixels, | |
Stride: screenWidth, | |
Rect: image.Rect(0, 0, screenWidth, screenHeight), | |
} | |
return img, nil | |
} |
thanks! I created a little bash script from this to take a screenshot and transfer it back:
takeScreenshot.sh
PS: the last command is for Mac only