Updating GM EBCM Checksum
- Gatecrasher
- Posts: 272
- Joined: Sat Apr 25, 2020 6:09 am
Re: Updating GM EBCM Checksum
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 ) 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.
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 ) 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 213 times
Re: Updating GM EBCM Checksum
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.
Re: Updating GM EBCM Checksum
maybe this will help
- Attachments
-
- reveng-2.1.1.zip
- (381.83 KiB) Downloaded 197 times
Re: Updating GM EBCM Checksum
That example code doesn't look so bad.
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.
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;
}
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
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
- Gatecrasher
- Posts: 272
- Joined: Sat Apr 25, 2020 6:09 am
Re: Updating GM EBCM Checksum
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.
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 185 times
Re: Updating GM EBCM Checksum
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
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 175 times
Re: Updating GM EBCM Checksum
I think I got it.
notated the pseudo code in the F021 doc(page 50).
From that I wrote some quick python, don't laugh- but it seems like it works. Works for both Cal and OS.
notated the pseudo code in the F021 doc(page 50).
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 212 times
Re: Updating GM EBCM Checksum
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!!
Just Amazing!!
Re: Updating GM EBCM Checksum
semi short lived excitement lol.
flashed a cal(cal only) with a bunch of data changed and managed to brick the damn thing.
JTAG 'works' but this tool still won't write to flash. Once I close the JTAG terminal and reopen, all the 'written' data reverts.
flashed a cal(cal only) with a bunch of data changed and managed to brick the damn thing.
JTAG 'works' but this tool still won't write to flash. Once I close the JTAG terminal and reopen, all the 'written' data reverts.
Re: Updating GM EBCM Checksum
So it returns back saying aaccepted using CANBus?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.
JTAG 'works' but this tool still won't write to flash. Once I close the JTAG terminal and reopen, all the 'written' data reverts.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726