Pages: [1]
Author Topic: MED9.1 Reading and Writing to the Serial EEPROM and RAM Mirror  (Read 23548 times)
Basano
Full Member
***

Karma: +90/-3
Offline Offline

Posts: 192



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 Wink

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

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  Smiley 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

E2P_BDM_read.bin

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

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 Huh

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  Cool

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.




« Last Edit: June 03, 2014, 03:24:51 AM by Basano » Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #1 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?
Logged
sweegie
Full Member
***

Karma: +10/-2
Offline Offline

Posts: 137


« Reply #2 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.
Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #3 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?
Logged
sweegie
Full Member
***

Karma: +10/-2
Offline Offline

Posts: 137


« Reply #4 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 Smiley 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.
Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #5 on: June 04, 2014, 03:21:21 AM »

Thanks! I've attached flash and iternal ROM.
Logged
oldcarguy85
Full Member
***

Karma: +15/-1
Offline Offline

Posts: 247


« Reply #6 on: June 04, 2014, 03:34:47 AM »

Man this is really impressive!!! You have made so much progress!!!! Truly great work!
Logged
technic
Full Member
***

Karma: +18/-5
Offline Offline

Posts: 227


« Reply #7 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  Huh
« Last Edit: June 04, 2014, 12:32:37 PM by technic » Logged
Basano
Full Member
***

Karma: +90/-3
Offline Offline

Posts: 192


« Reply #8 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 Sad

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!
Logged
SB_GLI
Hero Member
*****

Karma: +116/-10
Offline Offline

Posts: 1022


« Reply #9 on: June 05, 2014, 03:23:11 PM »

This thread, this forum... a lot of very impressive
Logged
sweegie
Full Member
***

Karma: +10/-2
Offline Offline

Posts: 137


« Reply #10 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 Smiley
Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #11 on: June 12, 2014, 12:47:04 PM »

Wow! Thank you!!! Will try it soon!
Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #12 on: June 13, 2014, 05:13:21 AM »

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

Could you tell me please how did you find it? I cant find any reference to it.  Huh
Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #13 on: December 16, 2014, 05:58:19 PM »

solved
« Last Edit: January 08, 2015, 04:40:57 PM by terminator » Logged
terminator
Sr. Member
****

Karma: +15/-4
Offline Offline

Posts: 425


« Reply #14 on: December 18, 2014, 02:52:33 PM »

solved
« Last Edit: January 08, 2015, 04:41:06 PM by terminator » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.025 seconds with 17 queries. (Pretty URLs adds 0s, 0q)