Updating GM EBCM Checksum

Disassembly, Reassembly, Tools and devleopment. Going deep with Hardware and Software.
User avatar
Gatecrasher
Posts: 272
Joined: Sat Apr 25, 2020 6:09 am

Re: Updating GM EBCM Checksum

Post by Gatecrasher »

Looks like I'm going to have to throw in the towel on this one. I don't have nearly enough of an understanding of what it's doing at a conceptual / mathematical level, so I've got no hope of turning it into some kind of script or code.

You'll want to download the attached data sheet to follow along.

The test is run as part of the mode A2 (report programmed status) routine. That subroutine starts at 0x128C. It runs some setup steps and eventually ends up at sub_E88.

sub_128C
>sub_AF8
>>sub_E28
>>>sub_E88

Once it gets to sub_E88, it runs the CRC using the parallel signature analyzer (PSA). It's described in section 8, page 46 of the PDF. In a nutshell, it's a hardware register that updates the CRC every time you do a read from memory.

So sub_E88 initializes that register with 0xFFFFFFFF and then sequentially reads through either the OS or calibration segment, using the start and end addresses found in the headers. Once that's done, it reads the CRC from the flash and compares that to the final result from the PSA register. Based on the result of that comparison, it sets or clears the error flag and then moves on to the rest of its business.

There's some pseudo-code further down the PDF that explains what it's doing. I just can't get my head around it. I found a simplified version of it in this PDF in appendix F (page 50).

https://www.ti.com/lit/ug/spnu501h/spnu ... e.com%252F

I still can't make sense of it. I was able to bang together some Python code that runs a standard CRC32, and I swapped out the poly and init values for what I think the TMS470 is using. It gives the expected result with standard CRC32 values, so I know the code itself works. But I don't get the correct output when I swap in the TMS470 poly and init values. Since I don't understand what it's actually doing, I can't really troubleshoot it. I don't know if my values are wrong, or the Python CRCmod code doesn't operate the same way the TMS470 hardware does. Like the TMS470 isn't a standard CRC or something. Someone who can read the pseudocode could probably answer that question.

There's a couple ways I can think of to get around this. The easiest one (says the guy who can't actually write working code :lol: ) would be to write a utility to calculate the correct CRC against the file and flash that as part of your modified calibration. This is a safety critical system, so I'd be in favor of keeping the error checking mechanisms.

It looks like you could maybe disable the calibration region CRC by modifying the last 4 bytes of the OS region header. The A2 routine runs the CRC against the OS region first. Then it checks the last 4 bytes of the OS header to see if there's a pointer to the calibration region. If that value is 0, it sets a pass flag and exits. The problem with that is, you'd need a modified OS with a valid CRC. But you'd only need to do that once, and hopefully never need to mess with the cal CRCs again. This also assumes the system never runs the CRC as a general health check. I haven't disassembled any of the code outside of a couple of diagnostic commands, so I have no idea what happens when it's running in its normal daily life. I do know there are other references to the PSA register address in the main OS code, so it's definitely possible it gets run in other circumstances.

The last thing I can think of is flashing it with your modified calibration, and then running an A2 command. Set up your JTAG adapter with a breakpoint at 0xE98. This is when the CRC routine reads the result of the PSA, but before it runs the compare against the CRC in flash. You could use the JTAG tool halt the processor at that location and manually read out the PSA register (0xFFFFFF40) to see what your processor calculated for the CRC. Then copy that value into your calibration file, reflash it, and see if everything is good to go.

If someone else figures out the math, can you post an explanation? I'd really like to understand this a little better.
Attachments
TMS470R1x System Module Reference.pdf
(730.05 KiB) Downloaded 211 times
RADustin
Posts: 162
Joined: Fri Oct 17, 2014 9:44 am

Re: Updating GM EBCM Checksum

Post by RADustin »

:punk:

I'll be digesting this. I'm out of town until Sunday and it'll take a little bit once I sit down, but I fully intend to have a calculator tool to do the work.

like you said, if we can't fully figure the math I can probably use jtag to get a good CS. I still can't flash with it but I think I can set breakpoints and halt it. To get an accurate halt though I will probably plug in the reset pin. This seemed to work the best but did give a few other issues when I played with it before.

I really don't want to disable the CS, although I may try at some point just to know. This is a learning experience as much as it is a desperate attempt to get my truck fully functional. I'd still like to go through the assembly. And maybe the assembly can help me find the tooth count locations? I think I found in RAM where the tooth locations are going...so maybe that could be traced back to rom?

you've definitely given me what appears to be enough info to have a full solution, and for that I'm extremely grateful. Thank You for your efforts and explanation. I'll be working more to finish out your efforts.
kostia111
Posts: 47
Joined: Mon Oct 21, 2019 4:58 am

Re: Updating GM EBCM Checksum

Post by kostia111 »

maybe this will help
Attachments
reveng-2.1.1.zip
(381.83 KiB) Downloaded 196 times
User avatar
Tazzi
Posts: 3422
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: Updating GM EBCM Checksum

Post by Tazzi »

That example code doesn't look so bad.

Code: Select all

uint32_t calculatePSA (uint32_t* pu32StartAddress,
uint32_t u32Length, /* Number of 32bit words */
uint32_t u32InitialSeed)
{
uint32_t u32Seed, u32SeedTemp;
u32Seed = u32InitialSeed;
while(u32Length--)
{
u32SeedTemp = (u32Seed << 1)^*(pu32StartAddress++);
if(u32Seed & 0x80000000)
{
u32SeedTemp ^= 0x00400007; /* XOR the seed value with mask */
}
u32Seed = u32SeedTemp;
}
return u32Seed;
}
Can you give me a bin with exact range I need to calculate for? And what you think the intial value (seed) and poly is?
We can also try brute force the value by looping through all combos. May take a while but will get their eventually.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Gatecrasher
Posts: 272
Joined: Sat Apr 25, 2020 6:09 am

Re: Updating GM EBCM Checksum

Post by Gatecrasher »

I used the attached file when I was trying to write my own program. It's the calibration region with the CRC removed from the last 4 bytes. So if you calculate that whole file, you should get 0xAE87BC86 as the CRC.

The code initializes the PSA register with 0xFFFFFFFF, and then starts reading from flash.

The reference manual says the primitive is based on bits 0,1,2,22 and 31. So that would give us 0x80400007 as the poly. That seems to track with what I read about a standard CRC32. But as I said, I don't have a good handle on this.
Attachments
22902328_caldata.bin
(32 KiB) Downloaded 184 times
RADustin
Posts: 162
Joined: Fri Oct 17, 2014 9:44 am

Re: Updating GM EBCM Checksum

Post by RADustin »

Just sitting down to dig into this.

As I understand it- by nature of the CRC math, if two known good files and their CRC values are XOR'd, then that will cancel any of the input or output XOR combinations....so basically strip the CRC down to just the polynomial. I looked into this just to try and get to the root poly first, then we can work on the input and output chores to get the whole algo. Since all the files are the same size, I don't think there are any output chores/modifications.

The attached files are cal 2327 XOR'd with 2328. I probably should have done 2327 and 2333 but this should still work. The CRC value would be 0x898FFB2B or if the data is reversed on input it would be 91F1DFD4. I attached the few permutations of the XOR of the two files.

Based on what I can figure, it seems like the poly is still something different. I've checked all the popular polys, and the one posted(0x80400007).

Also using this website to quickly calc the CRC for now, until we nail it better and then can work on some python. https://simplycalc.com/crc32-file.php
Attachments
XORoutput_reversed_nocs.bin
(32 KiB) Downloaded 176 times
XORoutput_reversed_inverted_nocs.bin
(32 KiB) Downloaded 183 times
XORoutput_nocs.bin
(32 KiB) Downloaded 173 times
XORoutput_inverted_nocs.bin
(32 KiB) Downloaded 174 times
RADustin
Posts: 162
Joined: Fri Oct 17, 2014 9:44 am

Re: Updating GM EBCM Checksum

Post by RADustin »

I think I got it. :punk:

notated the pseudo code in the F021 doc(page 50).
F0221 Flash API pg50 notated.JPG
F0221 Flash API pg50 notated.JPG (91.62 KiB) Viewed 3397 times
From that I wrote some quick python, don't laugh- but it seems like it works. Works for both Cal and OS.
Attachments
EBCM Checksum Calc 3.0.py
(1.22 KiB) Downloaded 210 times
RADustin
Posts: 162
Joined: Fri Oct 17, 2014 9:44 am

Re: Updating GM EBCM Checksum

Post by RADustin »

OK confirmed, the python will calc the correct CS. We are in business, now time to find the location for the tone ring tooth count.

Just Amazing!!
RADustin
Posts: 162
Joined: Fri Oct 17, 2014 9:44 am

Re: Updating GM EBCM Checksum

Post by RADustin »

semi short lived excitement lol.

flashed a cal(cal only) with a bunch of data changed and managed to brick the damn thing. :rant:

JTAG 'works' but this tool still won't write to flash. Once I close the JTAG terminal and reopen, all the 'written' data reverts.
User avatar
Tazzi
Posts: 3422
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: Updating GM EBCM Checksum

Post by Tazzi »

RADustin wrote:semi short lived excitement lol.

flashed a cal(cal only) with a bunch of data changed and managed to brick the damn thing. :rant:

JTAG 'works' but this tool still won't write to flash. Once I close the JTAG terminal and reopen, all the 'written' data reverts.
So it returns back saying aaccepted using CANBus?
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
Post Reply