NefMoto

Technical => Reverse Engineering => Topic started by: Basano on June 03, 2014, 03:11:19 AM



Title: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: Basano on June 03, 2014, 03:11:19 AM
Hi all,

I’ve been working on storing data in the Serial EEPROM (E2P) so that I can save variables across power cycles (ignition on / off). It's taken a lot of trial and error and I thought I'd share the results below. By no means is this the definitive guide on how to do this, but maybe it might help someone working on a similar idea. As always, take with a pinch of salt and back it up with your own research and experimentation ;)

1) The E2P is not accessed directly, rather the contents are mirrored to a section of RAM when the ecu starts up. The applications then read/write this section of RAM. When the ecu is powered down, the section of RAM is copied back into the E2P which saves the state of the variables. I can see the rationale behind this RAM mirror – accessing serial eeproms can be slow, plus there are only a finite amount of read/write cycles before the eeprom wears out! If the RAM contents have not been changed, then you don’t even need to store them back in the E2P. This is where checksums come in handy – if the checksum hasn’t changed, neither has the data.

2) First I had to find this RAM mirror. I think there are two ranges of RAM in the MED9.1. Internal RAM from 0x7F8000 – 0x7FFFFF and External RAM from 0x800000. I’ve attached a memory map to show what I mean. I read out the contents of the Internal RAM using the KWP commands DynamicallyDefineLocalIdentifier #2C, ReadDataByLocalIdentifier #21. I read out 16 bytes at a time and looped until I’d read the full range.

MPC500_MEMORY_MAP.pdf (http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=6159.0;attach=9591)

3) I compared this dump of the Internal RAM contents to the E2P read I had done previously using BDM and there it was. Nestled away at 0x7FAADC is a faithful mirror of the E2P! Attached are the dumps for those curious enough to stare at the hex  :) It’s easy enough to spot though, just look for the VIN which jumps out since it’s in ASCII. Contents may differ slightly since the BDM read is older than the RAM read, but you’ll get the idea. The address of the RAM is offset from 0x7F8000, so add 0x7F8000 to get the absolute address i.e:

Address 0x0 in file = 0x7F8000, 0x1 in file = 0x7F8001, 0x2 in file = 0x7F8002 etc

Internal_RAM_dump.bin (http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=6159.0;attach=9592)

E2P_BDM_read.bin (http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=6159.0;attach=9593)

4) Now that I’ve found this RAM mirror, compare it to the EEPROM as described in the FR - FU EEP_CONF 5.150.0 EEPROM-Layout on page 4529. The EEPROM is split up into logical blocks. Some blocks are more redundant than others, where the same block may have two copies in the EEPROM. However, you don’t need to worry about any of that, simply work with the RAM mirror and the RAM mirror <-> E2P low level stuff happens in the background. Here is block CALIB (0x0801). This block is mirrored at 0x7FABDC in the RAM mirror.

EEPROM_Layout.pdf (http://nefariousmotorsports.com/forum/index.php?action=dlattach;topic=6159.0;attach=9594)

0x7FABDC 08 01 00 80 80 80 80 00 00 80 00 80 80 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F6 FA 81

08 01  – Block Number
00 – Free bytes
F6 – Counter
FA 81 - Checksum

5) Each block has a little bit of free space and that’s what I wanted to use. In block CALIB above, there is a byte of free space at 0x7FABF7. I coded my assembly to write to this byte and then flashed my code onto the ecu and switched the ignition on and off to see what happens.

Code:
stb	r11, byte_7FABF7

Before ignition on/off
08 01 00 80 80 80 80 00 00 80 00 80 80 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 F7 FA 80

After ignition on/off
08 01 00 80 80 80 80 00 00 80 00 80 80 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F7 FA 80

It didn’t work! Even though I’ve got the correct byte and my code is indeed changing it from 0x00 to 0x02, the changed byte is not being committed from the RAM mirror to the E2P. Hmmm ???

6) Examining the block again, the last two bytes are a checksum. Thankfully this is a really straightforward checksum. Add all the bytes in the block together and then negate the result (negate means flip ones to zeroes and zeroes to ones). So I coded a bit more and created a little routine that does exactly that. In the code below, after I set the byte I want to save, I then update the checksum of the block. The checksum will change since I’ve changed the contents of the byte I want to use for storage.

Code:
stb	r11, byte_7FABF7	byte I want to use for persistent storage

li r7, 0 loop initialized
li r29, 0 sum of bytes
addi r11, r13, 0xFFFFABEC start at 0x7FABDC
lbzx r11, r11, r7
add r29, r29, r11
addi r7, r7, 1
cmpwi r7, 0x1E loop 30 times
blt loc_47C7A8
xori r29, r29, 0xFFFF negate (flip 1->0, 0->1)
sth r29, word_7FABFA store the new checksum

Flash again and test.

Before ignition on/off
08 01 00 80 80 80 80 00 00 80 00 80 80 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 F8 FA 7D

After ignition on/off
08 01 00 80 80 80 80 00 00 80 00 80 80 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 F9 FA 7C

And look at that, it's now being committed  8)

In summary, find the RAM mirror. Find some free space in one of the blocks therein. Every time you write to a byte (stb) in the block, update the checksum as well so that the block (containing your byte set to your desired value) will be committed to the E2P when the ignition is turned off and the housekeeping routines copy the RAM mirror to the E2P.

There are probably better ways of doing this and I’m sure there’s a routine that already exists to update the checksum. But my coding and abilities to read and understand the assembly are only basic.

Hope it helps.






Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on June 03, 2014, 05:56:48 AM
Great job! Thank you for this post! Really very useful!

Am I right older ME7 work with eeprom in the same way? I mean eeprom is not accessed directly too?


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: sweegie on June 03, 2014, 06:54:04 AM
Yes, Me7 serial eeprom is ram mapped too. Not sure how consistent the addresses are between versions though.


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on June 03, 2014, 07:16:11 AM
Thanks! Did you find EEPROM into RAM? Please throw me a bone, so I can find it in my r-box file.

Basano said that he saved RAM section and thats how he found EEPROM there. But I am not able to save RAM. Is there another way to find EEPROM?


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: sweegie on June 03, 2014, 11:44:58 PM
Thanks! Did you find EEPROM into RAM? Please throw me a bone, so I can find it in my r-box file.

Basano said that he saved RAM section and thats how he found EEPROM there. But I am not able to save RAM. Is there another way to find EEPROM?

Yep, i started playing around with retrieving the eeprom contents with ME7Logger, just for fun :) I found the addresses via disassembly of my bin - can you post a link to your current file? I'm away right now, but will be able to help out this weekend when I'm back home.


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on June 04, 2014, 03:21:21 AM
Thanks! I've attached flash and iternal ROM.


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: oldcarguy85 on June 04, 2014, 03:34:47 AM
Man this is really impressive!!! You have made so much progress!!!! Truly great work!


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: technic on June 04, 2014, 12:17:12 PM
Awesome!

I wonder if MED9 with partly encrypted eeprom (security access code and
component protection data) is decrypted before being stored in RAM mirror... Or afterwards  ???


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: Basano on June 05, 2014, 07:22:26 AM
Thanks guys,

Glad it’s been of some interest.

ME7 was a bit before my time, so I have very little knowledge on that. Assuming though that MED9.1 builds upon the same principles that Bosch used for ME7, then there should be similarities.

The ram locations will be quite specific to the bin. I’ve done all my disassembling and ram dumps using my Audi S3 bin – 387951. I did look at another bin from a Golf R – 510588. Although it’s the same MED9.1 ECU, the ram locations are different. I’m trying to think of a way that you can compare your MED9.1 bin to mine and match the ram locations, but matching ram is not nearly as easy as matching flash :( 

I’ve attached my bin anyway.

I haven't come across encryption yet but I'd hazard a guess that the ram mirror is always a direct copy of the e2p contents.

Good luck!


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: SB_GLI on June 05, 2014, 03:23:11 PM
This thread, this forum... a lot of very impressive


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: sweegie on June 11, 2014, 01:57:20 PM
Thanks! I've attached flash and iternal ROM.

Ok, looks like your eeprom is mapped in at 0x383DA4. Have fun :)


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on June 12, 2014, 12:47:04 PM
Wow! Thank you!!! Will try it soon!


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on June 13, 2014, 05:13:21 AM
Ok, looks like your eeprom is mapped in at 0x383DA4. Have fun :)

Could you tell me please how did you find it? I cant find any reference to it.  ???


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on December 16, 2014, 05:58:19 PM
solved


Title: Re: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror
Post by: terminator on December 18, 2014, 02:52:33 PM
solved