BMW M5 Forum and M6 Forums banner

1 - 20 of 84 Posts

·
Registered
Joined
·
1,345 Posts
Discussion Starter #1

I'm fairly happy with what I've done on the DME side of things and decided to take on a new challenge.... The SMG computer, a few years ago I helped a forum member and they sent me a spare TCU, it's sat in the garage till last month. When I decide it was time to take on this project. I'm on the hunt for one more TCU, so if anyone has a spare ;)


My main goal as of today is just to get the euro tune starting in S5 as the US one does. This annoys me to no end and would be considered a win in my opinion.



I have a rom file I can share, but probably shouldn't post and can provide you some hardware details, obviously I'm hoping someone else has interest too.


Some basic hardware details, the processor is a C167CS, it's the romless version running at 25mhz. It has one external 8k SRAM chip as well as the AM29F400 512k ROM chip, same one used in the MSS54. The Processor also has a few k internal ram that looks to be purely used for the stack. The processor is a pain the *** in that the addressing is segmented like the old x86 is in non 386 mode but the segments are referenced kind of funny.



The entry point is 0000 where the reset handler sits, it looks like when it comes it checks if it's in flashing mode or run mode based on some values in ROM. I'm gonna verify this once I get the ROM sockets, been waiting over a month for them(I think the post office lost them) as I'm not soldering and soldering a rom chip every time I want to test a change. Once it's up it's pretty much interrupt driven waiting for inputs, timers , adc, ect or CAN messages.



The "tune" or data segment is located at 0x07800 and doesn't follow the DME conventions of "maps" .



Most of the last 2 weeks on this has been getting organized and figure a lot of the hardware details, Siemens did the layout for the board I think and they're assholes, there a few items that had me scratching my head for a few days till I figure it out. I also spent some time generating binaries from the 0das so I can overlay them over a working rom image and compare them to help find locations of value. I'm thinking the E46 csl tune would have some more keys to the puzzle.


Anyway if anyone has interested I can share the ROM file and answer any question on things I know thus far.












 

Attachments

·
Registered
Joined
·
101 Posts
Another brilliant post by Ferris. I find it highly irritating having to increase the shift setting every time I start the car.

Subscribed!
 

·
Registered
Joined
·
95 Posts
After seeing your post I thought I'd throw Y7842207.0da (Euro SMG3) and Y7842209.0da (US SMG3) into WinOLS and see what differences popped up.


It looks like the GDSMG3 0das are 16bit and little endian. Suprisingly there are only 36 changes between the 2.


 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #5 (Edited)
After seeing your post I thought I'd throw Y7842207.0da (Euro SMG3) and Y7842209.0da (US SMG3) into WinOLS and see what differences popped up.


It looks like the GDSMG3 0das are 16bit and little endian. Suprisingly there are only 36 changes between the 2.


Correct the changes are rather small, from what I can tell the first change is a configuration parameter that gets copies into the ram and used out of ram. I started breaking down the bits to see what they mean. I can post that section later today.

btw I <3 your 0do to bin but it puked on these files :p and made me have to write my own.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #6
Well it's been unremarkable but progress none the less. The sockets came but there were some resistors in the way, since it's bigger than the rom chip so I had to modify the socket a bit. Got it soldered up, and buzzed all the lines(siemens was nice enough to leave a ton of test points) and plugged the TCU into my car and got it adapted. I probably should've done that first to confirm the tcu actually worked but either way it does and my copied rom image works so that's all pretty good news in terms of hardware.


I am dumb I should've probably written the program file out first as I could've skipped a bunch of steps. Either way though
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #8
Well it's been unremarkable but progress none the less. The sockets came but there were some resistors in the way, since it's bigger than the rom chip so I had to modify the socket a bit. Got it soldered up, and buzzed all the lines(siemens was nice enough to leave a ton of test points) and plugged the TCU into my car and got it adapted. I probably should've done that first to confirm the tcu actually worked but either way it does and my copied rom image works as does the socket, I drink way too much coffee to be near a soldering iron, so that's all pretty good news in terms of hardware.


I am dumb I should've probably written the program file out first as I could've skipped a bunch of steps. Either way though as one would one suspect but I had to step through...


The the board comes and the reset vectors is at 0x0000, it runs a bunch tests , some seems extraneous like it tests all the registers, and searches for magic numbers in ram and does things based on them. There is a ton of redundancy, like the chip has a watch dog but the voltage regulator does too and the processor has to go out and bit flip a line to it or reset gets asserted again. It checks for magic number in rom too.



Eventually if everything checks out it jumps to the program at 0x10000 this is what the .0pa contains.



I was mistaken about the first data difference, 0x78090, I believe it's a checksum verified initially by the bootloader, going to figure out the start and end addresses as well as the algorithm this week.
 

Attachments

·
Registered
Joined
·
816 Posts
After seeing your post I thought I'd throw Y7842207.0da (Euro SMG3) and Y7842209.0da (US SMG3) into WinOLS and see what differences popped up.


It looks like the GDSMG3 0das are 16bit and little endian. Suprisingly there are only 36 changes between the 2.


That was gonna be my suggestion as well - diff the two files and look at the change. Google says 0da files are intel hex, so at least the encoding is public https://en.wikipedia.org/wiki/Intel_HEX

One thing I've been curious about is whether the SMG reset thing (both paddles in, while neutral) is sent over PT-can, or it's just the paddle clicks and the logic resides in the smg controller itself. Both paddles for neutral would be awesome imo.
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #13
That was gonna be my suggestion as well - diff the two files and look at the change. Google says 0da files are intel hex, so at least the encoding is public https://en.wikipedia.org/wiki/Intel_HEX

One thing I've been curious about is whether the SMG reset thing (both paddles in, while neutral) is sent over PT-can, or it's just the paddle clicks and the logic resides in the smg controller itself. Both paddles for neutral would be awesome imo.
Paddles are input signals to the smg. I'll post the source code to convert 0xa to bin
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #14 (Edited)
0xa to hex

Written in 1/2 hour while on a conference call, it's not pretty but it works, I didn't care about the checksums


Code:
#include stdio.h 
#include stdlib.h

#include stdio.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h
#include memory.h


int processRecordLine(char * pLine,size_t lineSize,FILE *output,unsigned int *nAddress){

    char buffer[64];
    int  lineAddress=0;
    int     recordType=0;
    int     data;

    int nByteCount;
    if(lineSize>=8){

        memcpy(buffer,pLine,2);
        buffer[2]=0x00;
        nByteCount=strtol(buffer,NULL,16);
        lineSize-=2;
        pLine+=2;

        memcpy(buffer,pLine,4);
        buffer[4]=0x00;
        lineAddress=strtol(buffer,NULL,16);
        lineSize-=4;
        pLine+=4;


        memcpy(buffer,pLine,2);
        buffer[2]=0x00;
        recordType=strtol(buffer,NULL,16);
        lineSize-=2;
        pLine+=2;

        switch(recordType){
        case 00:

            fseek(output,(*nAddress)+lineAddress,SEEK_SET);
            if((lineSize-2)>=(nByteCount*2)){

                while(nByteCount--){
                    buffer[0]=*pLine++;
                    buffer[1]=*pLine++;
                    buffer[2]=0;
                    data=strtol(buffer,NULL,16);
                    fwrite(&data,1,1,output);
                }
            }
            break;
        case 01:
            return 1;
            break;
        case 02:
            break;
        case 03:
            break;
        case 04:
            if((lineSize-2)>=(2*2)){
                buffer[0]=*pLine++;
                buffer[1]=*pLine++;
                buffer[2]=*pLine++;
                buffer[3]=*pLine++;
                buffer[4]=0;
                *nAddress=strtol(buffer,NULL,16)<<16;
            }

            break;
        case 05:
            break;




        }


    }

    return 0;
}



int main(int argc,char *aa[]) {

    FILE *fInput=0;
    FILE *fOutput=0;
    int nReturn=-1;
    size_t nRead,nBufferSize = 256;
    char *pDataBuffer=0x00;
    char *pDataPtr;
    int nLineNumber=0;
    unsigned int nAddress=0;
    int    done=0;

    if(argc!=3){
        printf("Usage : ./bmwhex2bin <in> <out> \n");
        goto exit;
    }




    fInput = fopen (aa[1],"r");
    if(fInput==NULL){
        printf("file not found.\n");
        goto exit;
    }

    fOutput = fopen (aa[2],"w+");
    if(fOutput==NULL){
         printf("can't create output.\n");
         goto exit;
    }

    pDataBuffer = (char *) malloc (nBufferSize);
    memset(pDataBuffer,0x00,nBufferSize);
    while(!done && (nRead=getline(&pDataBuffer,&nBufferSize,fInput))!=-1){
        nLineNumber++;
        pDataPtr=pDataBuffer;
        switch(*pDataPtr++){
        case ':':
            if(processRecordLine(pDataPtr,nRead-1,fOutput,&nAddress)==1)
                done=1;
            break;
        case '$':
            printf("line %d $ %s",nLineNumber,pDataPtr);
            break;
        case ';':

            break;
        default:
            printf("line %d unknown prefix\n",nLineNumber);
            break;
        }
        memset(pDataBuffer,0x00,nBufferSize);
    }




exit:
    if(pDataBuffer)
        free(pDataBuffer);
    if(fInput)
        fclose(fInput);
    if(fOutput)
        fclose(fOutput);

    return nReturn;
}
</out></in></memory.h></unistd.h></fcntl.h></sys></sys></stdio.h></stdlib.h></stdio.h>
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #15
Since there is a lot of code it's kind of a waste of time for one person to pour over and documented the exact flow, esp seeing some times the jumps/calls are dictated by pointers or registers set higher up in the call stack.. So I pondered my approach last night and came up with a much simpler idea.



Since all the flash is external and I know the data areas of interested I'm going to hook up the a logic analyzer to the data lines and wait for those areas to be accessed and correlate the the accessing code address, then just target that code.


So they'll be no progress this week most likely, as I wait for the analyzer, the positive side is I can use it in my business so it's write off :)
 

·
Registered
Joined
·
95 Posts
As you've got a spare TCU knocking around, can you try flashing a modified 0DA with WinKFP? I've done it previously with SMG2 and it flashes fine with just the end of line checksum corrected and then the overall file checksum corrected with NCSDummy.


Thinking out loud, the chances are that the change to tell the car which gear to start in is going to be one of the changes that is a single 16 bit that isnt surrounded by other changes, such as those changes in the maps I highlighted. There aren't many of those so it could be nailed in a few flashes :)
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #17
As you've got a spare TCU knocking around, can you try flashing a modified 0DA with WinKFP? I've done it previously with SMG2 and it flashes fine with just the end of line checksum corrected and then the overall file checksum corrected with NCSDummy.


Thinking out loud, the chances are that the change to tell the car which gear to start in is going to be one of the changes that is a single 16 bit that isnt surrounded by other changes, such as those changes in the maps I highlighted. There aren't many of those so it could be nailed in a few flashes :)

Well i'm burdened by wanting to understand exactly how it works and seeing what else could be done. But yes I suppose that approach would work as well for goal one





I have a rom burner and socketed the chip so I can just do whatever and see what happens. Once we pin changes down though I figured we'd give out details to the community on how using the NCSDummy way.
 

·
Registered
Joined
·
95 Posts
Well i'm burdened by wanting to understand exactly how it works and seeing what else could be done. But yes I suppose that approach would work as well for goal one

I have a rom burner and socketed the chip so I can just do whatever and see what happens. Once we pin changes down though I figured we'd give out details to the community on how using the NCSDummy way.
:grin

I guess once you've had the location of the change you can work back in IDA and work back through the functions that reference it?

Fair enough, I should probably stop hijacking your thread now anyway :)
 

·
Registered
Joined
·
1,345 Posts
Discussion Starter #19
:grin
Fair enough, I should probably stop hijacking your thread now anyway :)

No way dude I value the input...


because the way the C166 segments and uses pages it doesn't appear to properly figure things out on it's own with some coaching it's better but that's why I kind of need an idea of what's up.



I'll try a random word today in the diff and see what happens. why not, it'll at least prove it if does use a data checksum or not.
 

·
Registered
Joined
·
95 Posts
Something else I forgot to mention, when I was messing with WinOLS earlier I noticed the number of changes jumped to 533. When I revert the 4 maps shown in one of my earlier posts that changes to 400.



I think I can probably slim that 400 down to a much smaller number if we rule out 'clusters' of changes and the junk at the start/end of the file.
 
1 - 20 of 84 Posts
Top