Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

collect rm2 panel IDs #35

Closed
raisjn opened this issue Nov 9, 2020 · 12 comments
Closed

collect rm2 panel IDs #35

raisjn opened this issue Nov 9, 2020 · 12 comments

Comments

@raisjn
Copy link
Member

raisjn commented Nov 9, 2020

I'm trying to get a native framebuffer library going to avoid relying on xochitl, but there are possibly three different panels to support. Can those with a reMarkable 2 run the following in an SSH session, so I can verify that I'm looking in the right place for the panel identifier?

dd if=/dev/mmcblk2boot1 bs=1 count=120 | hexdump

Originally posted by @tadfisher in #34 (comment)

@raisjn raisjn changed the title I'm trying to get a native framebuffer library going to avoid relying on xochitl, but there are possibly three different panels to support. Can those with a reMarkable 2 run the following in an SSH session, so I can verify that I'm looking in the right place for the panel identifier? collect rm2 waveforms Nov 9, 2020
@raisjn raisjn changed the title collect rm2 waveforms collect rm2 panel IDs Nov 9, 2020
@raisjn
Copy link
Member Author

raisjn commented Nov 9, 2020

@tadfisher: please use this issue or post in https://github.com/ddvk/remarkable2-framebuffer regarding waveforms and panel IDs. the panel identifier also needs some massaging in order to figure out which waveform to use.

@jinnovation: please be careful with what you post as that contains your rM serial number. if you don't mind, feel free to repost.

@EBNull
Copy link

EBNull commented Nov 9, 2020

reMarkable: ~/ cat /sys/devices/soc0/machine
reMarkable 2.0

reMarkable: ~/ dd if=/dev/mmcblk2boot1 bs=1 count=120 | hexdump
120+0 records in
120+0 records out
0000000 0000 0f00 4d52 3131 2d30 3330 2d39 3535
0000010 3337 0032 0000 460c 4d55 3232 3330 3233
0000020 3432 0038 0000 420f 4459 3032 3830 3732
0000030 3030 3132 3930 0000 1900 5245 414c 5238
0000040 3257 5531 5642 3030 4d38 414e 2054 312d
0000050 352e 0032 0000 540a 5345 5354 445f 4e4f
0000060 0045 0000 0000 0000 0000 0000 0000 0000
0000070 0000 0000 0000 0000
0000078

@raisjn
Copy link
Member Author

raisjn commented Nov 9, 2020

Do you know which WBF file was loaded? (It should be in xochitl or remarkable-shutdown output, I think)

@raisjn
Copy link
Member Author

raisjn commented Nov 9, 2020

i believe the format of mmcblk2boot1 is like so:

<separator><RM serial><separator><serial2><separator><serial3><separator><serial4><separator>TESTS_DONE

separator is three bytes of 0, then 2 bytes 1 byte.

  1. RM serial starts with RM110-
  2. serial2 is 12 characters
  3. serial3 is 15 characters
  4. serial4 is 25 characters (likely panel ID after asking bokluk)

@EBNull
Copy link

EBNull commented Nov 9, 2020

I'm not precisely sure how to check which is loaded, but I made some guesses:

reMarkable: ~/ journalctl -u xochitl | grep -i wbf
Nov 02 22:09:48 reMarkable xochitl[216]: Reading waveforms from /usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf
Nov 03 01:02:12 reMarkable xochitl[698]: Reading waveforms from /usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf
Nov 03 01:03:39 reMarkable xochitl[728]: Reading waveforms from /usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf
Nov 04 17:38:20 reMarkable xochitl[880]: Reading waveforms from /usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf
reMarkable: ~/ ls /usr/share/remarkable/ -l | grep wbf
-rw-r--r--    1 root     root        282610 Sep 22 21:31 320_R259_AFAB21_ED103TC2M1_TC.wbf
-rw-r--r--    1 root     root        285149 Sep 22 21:31 320_R292_AFBC21_ED103TC2M1_TC.wbf
-rw-r--r--    1 root     root        287347 Sep 22 21:31 320_R299_AFC421_ED103TC2U2_VB3300-KCD_TC.wbf

reMarkable: ~/ md5sum /usr/share/remarkable/*.wbf
76aaa220ee594efa3fec850d750c8c8e  /usr/share/remarkable/320_R259_AFAB21_ED103TC2M1_TC.wbf
c774705291b169643cac8b48dbc1887c  /usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf
5ddd01cda24b445457a80184c2d56d99  /usr/share/remarkable/320_R299_AFC421_ED103TC2U2_VB3300-KCD_TC.wbf

Let me know if you'd like me to check anything else. I'm familiar with linux and such but less so with reMarkable specifically so expanding on device specific details will help ensure turnaround time is quick.

@EBNull
Copy link

EBNull commented Nov 9, 2020

i believe the format of mmcblk2boot1 is like so:

<separator><RM serial><separator><serial2><separator><serial3><separator><serial4><separator>TESTS_DONE

separator is three bytes of 0, then 2 bytes.

1. RM serial starts with RM110-
2. serial2 is 12 characters
3. serial3 is 15 characters
4. serial4 is 25 characters (likely panel ID after asking bokluk)
reMarkable: ~/ dd if=/dev/mmcblk2boot1 bs=1 count=120 | hexdump -C
120+0 records in
120+0 records out
00000000  00 00 00 0f 52 4d 31 31  30 2d 30 33 39 2d 35 35  |....RM110-039-55|
00000010  37 33 32 00 00 00 0c 46  55 4d 32 32 30 33 33 32  |732....FUM220332|
00000020  32 34 38 00 00 00 0f 42  59 44 32 30 30 38 32 37  |248....BYD200827|
00000030  30 30 32 31 30 39 00 00  00 19 45 52 4c 41 38 52  |002109....ERLA8R|
00000040  57 32 31 55 42 56 30 30  38 4d 4e 41 54 20 2d 31  |W21UBV008MNAT -1|
00000050  2e 35 32 00 00 00 0a 54  45 53 54 53 5f 44 4f 4e  |.52....TESTS_DON|
00000060  45 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |E...............|
00000070  00 00 00 00 00 00 00 00                           |........|
00000078

The "separators" appear to be length prefixes of 4 bytes:
0xf == 15 == len(RM110-039-55732)
0xc == 12 == len(FUM220332248)
0xf == 15 == len(BYD200827002109)
0x19 == 25 == len(ERLA8RW21UBV008MNAT -1.52)
0xa == 10 == len(TESTS_DONE)

@EBNull
Copy link

EBNull commented Nov 9, 2020

The function inspecting /dev/mmcblk2boot1 starts at 0x002b8aac within xochitl with md5sum aaa77163501618b0cfae54843505df88.

An early glance suggests that xochitl treats these as length prefixed also (edit) and that it expects 5 entries in the array total (which matches what we have).

@raisjn
Copy link
Member Author

raisjn commented Nov 9, 2020

sounds like a mystery solved, thank you! :)

hopefully that's enough for @tadfisher to start on the native fb drivers

@EBNull
Copy link

EBNull commented Nov 10, 2020

xochitl opens each wbf file in the directory and compares the FPL_LOT code within to one of the fields read from /dev/mmcblk2boot1. When a match is found that WBF file is used. The theory that the correct waveform file is dependent on the lot code recorded in one of these four fields seems correct to me.

Interestingly I think the code also checks for wbf files at /var/lib/uboot but my rm2 has no WBF files there.

The function at 0x002b859c (again, in md5 aaa77163501618b0cfae54843505df88) is the one that opens each WBF for comparison.

I'm poking and making educated guesses (so this may be wrong) but it seems the lot code is looked for in the WBF file at offset 0xe.

Within the WBF offset 0x04 (bytes 5-8) is required to match the file length (in this case 0x000459dd == 285149 bytes).

Within the WBF offset 0x0e (bytes 15-16) is the FPL_LOT code (in this case 0x0124 ?) which is decoded from the original four fields.

reMarkable: ~/ dd if=/usr/share/remarkable/320_R292_AFBC21_ED103TC2M1_TC.wbf bs=1 count=120 | hexdump -C
00000000  55 8e 90 9d dd 59 04 00  6e 1f 00 00 11 00 24 01  |U....Y..n.....$.|
00000010  19 bc 21 51 00 ce 00 85  55 00 00 00 40 00 00 f2  |..!Q....U...@...|
00000020  5f 00 00 01 04 07 0d 03  ff fc 01 00 00 00 00 77  |_..............w|
00000030  00 03 06 09 0c 0f 12 15  18 1b 1e 21 26 2b 30 47  |...........!&+0G|
00000040  1d 33 32 30 5f 52 32 39  32 5f 41 46 42 43 32 31  |.320_R292_AFBC21|
00000050  5f 45 44 31 30 33 54 43  32 4d 31 5f 54 43 87 7f  |_ED103TC2M1_TC..|
00000060  00 00 7f ef 00 00 ef 5f  01 00 60 cf 01 00 d0 3f  |......._..`....?|
00000070  02 00 41 af 02 00 b1 1f                           |..A.....|
00000078

@EBNull
Copy link

EBNull commented Nov 10, 2020

Figured it out:

The function is decodeBarcode(char* fp_barcode, decoded_data* dd) at 002b6e44 in aaa77163501618b0cfae54843505df88.

It takes as input the fourth length-prefixed field from /dev/mmcblk2boot1 and a memory address to place the decoded data.

The type it decodes into looks something like:

struct decoded_data {
    char[25] serial;
    char unknown1;
    char unknown2;
    int fpl_lot_id; // offset 0x28
    int unknown3;
}

The code is a bit strange:

  1. Assume decoded_data starts full of zeros.
  2. First it copies all 25 bytes of the serial into offset 0 serial
  3. Then it copies the character at offset 5 into unknown1
  4. Then it selects a starting value for fpl_lot_id:
if ((serial[6] > 0x41 & 0xff) < 8) {
  fpl_lot_id = serial[6] - 0x41 & 0xff
} else {
  if ((serial[6] - 0x4a & 0xff) < 5) {
    fpl_lot_id = (serial[6] - 0x4a) * 10 + 0xb4;
  } else {
    if ((serial[6] - 0x51 & 0xff) < 10) {
      fpl_lot_id = (serial[6] - 0x51) * 10 + 0xe6;
    } else if (serial[6] != '0') {
      // bad serial
  }
}
  1. Then, if serial[7] is numeric, it is added to fpl_lot_id.

Here's how it works out with my serial:

serial = "ERLA8RW21UBV008MNAT -1.52"
// serial[6] == W == 87 == 0x57
// serial[7] == 2
// first condition fails, 0x57 > 0x41
// second condition fails, 0x57 - 0x4a = 0x16; 0x16 > 5
// third condition passes, 0x57 - 0x51 & 0xff = 6; 6 < 10
fpl_lot_id = (0x57 - 0x51) * 10 + 0xe6 // = 0x122
// adjust lot because serial[7] is 2:
fpl_lot_id += 2
// thus fpl_lot_id == 0x124

So the calculated 0x124 from my serial matches the 0x124 result within the WBF file at offset 0x0e as mentioned in #35 (comment)

Thus the algorithm will let you pick the correct wbf just as xochitl does:

  1. Read the fourth field from /dev/mmcblk2boot1 (each field starts with a 4 byte length). This is your display barcode.
  2. Apply the above algorithm to get a lot code.
  3. Scan all WBF files in /var/lib/uboot (none) and /usr/share/remarkable (you'll find three).
  • For each WBF file, read the unsigned short at offset 0x0e. This is the WBF's FPL_LOT code. If this unsigned short matches your lot code, you've found the correct WBF file for the display.

@tadfisher
Copy link

@EBNull This is excellent, I've been messing with this function in ghidra for hours.

FWIW, /var/lib/uboot/zplash is a gzipped raw binary loaded to display the splash screen, and it contains five functions and a very simplified waveform. It could be useful to study this to determine how they apply the waveform to the bitmap data. LMK if you would like a ghidra export.

@raisjn
Copy link
Member Author

raisjn commented Nov 10, 2020

for further reversing discussion, please open an issue in ddvk/remarkable2-framebuffer (or any other channel you are comfortable with)

@raisjn raisjn closed this as completed Nov 10, 2020
@rmkit-dev rmkit-dev locked as off-topic and limited conversation to collaborators Nov 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants