GM E38 E67 Kernel/Bootloader Development Extravaganza

Bosch Motronic etc ECUs and PCMs
Posts: 15
Joined: Thu Jun 11, 2015 11:53 am

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby tek1229 » Sun Aug 11, 2019 10:12 am

This may or may not help you, you might already have this, but someone is working on making E38 ecu tuning open source.. This is not my work, but I am definitely interested in it.. If you need/want the seed/key algo for E38 it's posted there.. I need it so few I would just grab it from a session log of sps programming for myself but this would be good to add to my library and maybe even automate my little vin change program a little.. lol..
https://github.com/opensourcetuning/GM

User avatar
Posts: 2130
Joined: Thu May 17, 2012 8:53 pm
Location: WA

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tazzi » Sun Aug 11, 2019 11:59 am

Yeah I saw some posts on Facbook about all of this blowing up, very very interesting.
Image

Posts: 136
Joined: Tue Oct 16, 2012 12:17 pm
Location: Perth

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tre-Cool » Sun Aug 11, 2019 11:32 pm

1 thing that i could see being potentially useful, would be writing different ETC/Pedal tables.

none of the tuning software out there does that.

Posts: 15
Joined: Thu Jun 11, 2015 11:53 am

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby tek1229 » Tue Aug 13, 2019 3:03 am

The guy on fb is posting some interesting reading material for the E38 on his new forum.. hopefully plugging another forum is ok here?? it's just getting started, I could post the files here, probably in another post if needed??

http://www.opensourcetuning.com

User avatar
Posts: 2130
Joined: Thu May 17, 2012 8:53 pm
Location: WA

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tazzi » Sun Feb 02, 2020 11:47 pm

Been working on understanding powerpc a bit more over the weekend.. and FINALLY had nutted out what happens when using the instruction rlwimi

so.. rlwimi - rotate left word immediate then mask insert

using the following example:

rlwimi r6, r5, 3, 0, 29

Assuming r5 = 0x1122 3344 (binary = 0001 0001 0010 0010 0011 0011 0100 0100)
and r6 = 0x4433 2211 (binary = 0100 0100 0011 0011 0010 0010 0001 0001‬)

1) Rotate r5 left by 3bits
before rotation: 0001 0001 0010 0010 0011 0011 0100 0100
After rotation: 1000 1001 0001 0001 1001 1010 0010 0000
hex value is now: 0x8911 9A20‬

2) The mask to use is 0,29, which means every bit from 0 to 29 is set to 1. In PPC, the MSB is bit 0, and LSB is bit 31.
So this mask would be: 1111 1111 1111 1111 1111 1111 1111 1100
hex value is 0xFFFF FFFC

3) Next, for every bit set as 1 in the MASK, this will REPLACE the bit of R6 with the bit in R5. Any 0 bits in the mask means the bit in R6 is left alone.
Looking at the above, only bit 30 and 31 are preserved in R6, all other bits will be replaced with whats stored in R5.

So we end up with:
1000 1001 0001 0001 1001 1010 0010 0001

So finally we end up with: 8911 9A21‬

This.. has 100% driven me crazy trying to understand. I had to have it written down or would go crazy. :wtf: :lol:



Now.. whys this so important? This kind of command is used extensively through the E38 operating system, along with GMs kernel so its important to understand it well. This is used alot for the CAN regsiters, interrupts and external flash handling routines.
A common example which came up frequently was the following:
r6,r7,0x5,0x1f,0x1f
where:
r7 = 0
r6 = some important register (Like interrupts or canbus)

since r7 is 0, it could be rotated an unlimited times and makes no difference. Its funny that the compiler occasionally sets the 'rotation bit' to something like seen here as 5, since rotating 0 by 5 is still 0!
Next, this sets a mask of bit 31 to 31. This means we have 0000 0000 0000 0000 0000 0000 0000 0001
Since r7 is 0, this means every bit that is a 1 in the above mask will set the same bit in r6 as 0, thus in this case its bit 31.
This is essentially a simple way of setting/disabling specific bits in a register. In C is should be: r6 |= ((r7<<5) & mask)

I think I got that above c calc correct.. but regardless... it makes SO much more sense with it written out nicely.
Image

Site Admin
User avatar
Posts: 6163
Joined: Sat Feb 28, 2009 8:34 pm

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby antus » Mon Feb 03, 2020 9:59 am

:thumbup:
Have you read the FAQ? For lots of information and links to significant threads see here: viewtopic.php?f=7&t=1396

User avatar
Posts: 2130
Joined: Thu May 17, 2012 8:53 pm
Location: WA

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tazzi » Mon Feb 03, 2020 11:29 am

Onto the next saga...

Now the flashchip..
example from here: http://www2.lauterbach.com/pdf/flash_diagnosis.pdf
Data.Set 0xa0001554 %Long 0xaa
Data.Set 0xa000aa8 %Long 0x55
Data.Set 0xa0001554 %Long 0x90

So this writes values of:
0xAA to loc 0x1554
0x55 to loc 0xAA8
0x90 to loc 0x1554

What this does is which the flash to ID mode

Looking at the data sheet though it says to do the folowing:
0xAA to loc 555
0x55 to loc 2AA
0x90 to loc 555

The data sheet explicitly says command definitions for x32 mode, so possible Im looking for a different mode.

0x555 = 0000 0101 0101 0101‬
0x1554 = 0001 0101 0101 0100

0x2AA = 0010 1010 1010
0xAA8 = 1010 1010 1000

Looking at these.. its shifting left by two... for what happens in factory kernel and also examples

actually.. so if command is 555 and bus width is 2... 0x555<<2 = 0x1554.

Dunno if thats correct, but Im rolling with it since its the only thing that works currently.
Image

User avatar
Posts: 2130
Joined: Thu May 17, 2012 8:53 pm
Location: WA

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tazzi » Tue Feb 04, 2020 10:59 pm

progress... slowly but surely.

Have got a custom kernel to spit out a can message constantly on the bus. Only lasts for very short time before ecu resets, which is due to the WDT not being satisfied.. but thats next on the list.
I have some coding in for reading a CAN frame.. although currently cant test till the WDT is sorted.

I was just happy its writing a frame :lol:

Reading the flash seems to be alot easier to do, doesnt require alot of messing about. The loop for actually reading the data, then putting into a CAN frame is actually very small. But the complexity comes in counting how any bytes have been retrieved and making the returned frame SAE compliant (otherwise my J tool will have a fit).

What I mean by this is.. say I have these 8 bytes of data: 11 22 33 44 55 66 77 88
Putting those into a can frame means:
7E8 21 11 22 33 44 55 66 77
7E8 22 88
So.. the last byte moves to the second line. This means a bit of fancy work with isolating bytes and saving them into another register then adding next bytes to it and continuing are required. It just gets a little complicated is all.

only way I can think around that is to read out 7 lots of words (4bytes) at a time. So 28bytes like this.
7E8 21 11 22 33 44 11 22 33
7E8 22 44 11 22 33 44 11 22
7E8 23 33 44 11 22 33 44 11
7E8 24 22 33 44 11 22 33 44
So for the bulk of the transfer, will setup 4 frames at a time and send them all out.

If chosen to read say 100bytes (0x64) then it would do 2 full 28byte transfers and on the last one, it will do whatever the remainder is.
It just hurts my head having to move the bytes so much between the registers to make it happy, which is where all the rlwinm and rlwimi come into place
Image

User avatar
Posts: 2130
Joined: Thu May 17, 2012 8:53 pm
Location: WA

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby Tazzi » Tue Feb 04, 2020 11:25 pm

Yeah right thinking about that... using example data 11 22 33 44 and 55 66 77 88
lwz r11, flashadd //11 22 33 44
lwz r12, flashadd+4 //55 66 77 88

rlwimi r8,r11,23,8,1f //rotateleft 23bytes, becomes 44 11 22 33.. then ignores first 8bits to become 00 11 22 33 (hopefully did that right..)
lis r9, 0x2100 //2100 0000
ori r9,r8 //21 11 22 33

li r8,0
rlwimi r8,r11,23,0,7 //44 11 22 33.. 44 00 00 00
rlwimi r8,r12,0,7,1f //no rotate, keep first bits, add the the rrest from r12 = 44 55 66 77

Can frame 1 = 21 11 22 33 44 55 66 77

now to continue to madness :lol:
Image

Posts: 19
Joined: Mon Oct 21, 2019 4:58 am

Re: GM E38 Kernel/Bootloader Reverse Engineering Extravaganz

Postby kostia111 » Wed Feb 05, 2020 2:03 am

hello !
why not use a lot of frame message
the same way as when programming a block
then it will be possible to transfer about 4k
in one message
or use a standard service
ReadMemoryByAddress ($23) Service.
maybe I'm writing stupidity
and misunderstood you
English is not my native language
maybe you miss some details
before programming
some preparation takes place:
interrogation of the tire, transfer to the dianostic mode,
prohibition of normal communication,
poll identifiers to fill
some buffers (which may be needed when programming),
putting the unit into programming mode,
after that already security unlock
loading kernel in ram
I think part of it
need to do before
attempt to read block

Startup
Setup Base Mapping Matrix
Determine subnet configuration
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
Available subnets: HS-CAN
MessageType=1, <[.H..]00 00 01 01 FE 02 1A B0 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 02 1A B0 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 03 5A B0 11 FF FF FF FF [0012]
MessageType=2, >[.H..]00 00 07 EA 03 5A B0 18 AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 03 5A B0 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 06 43 03 5A B0 28 [0008]
Base Mapping Matrix:
ECU 0x11 on HS-CAN (ReqCANId: 0x7E0, RspCANId: 0x7E8)
ECU 0x18 on HS-CAN (ReqCANId: 0x7E2, RspCANId: 0x7EA)
ECU 0x40 on HS-CAN (ReqCANId: 0x241, RspCANId: 0x641)
ECU 0x28 on HS-CAN (ReqCANId: 0x243, RspCANId: 0x643)
InitiateDiagnosticOperation (0x10) service with sub-func. 0x02 (disableAllDTCs)
MessageType=1, <[.H..]00 00 01 01 FE 02 10 02 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 02 10 02 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 01 50 FF FF FF FF FF FF [0012]
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 07 EA 01 50 AA AA AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 01 50 B0 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 06 43 01 50 [0006]
MessageType=1, <[.H..]00 00 01 01 FE 01 28 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 28 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 01 68 FF FF FF FF FF FF [0012]
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 07 EA 01 68 AA AA AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 01 68 B0 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 06 43 01 68 [0006]
ReportProgrammedState (0xA2) service
MessageType=1, <[.H..]00 00 01 01 FE 01 A2 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 A2 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 02 E2 00 FF FF FF FF FF [0012]
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 07 EA 02 E2 00 AA AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 02 E2 00 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 06 43 02 E2 00 [0007]
Number of detected programmable ECUs: 4
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
Enable Programming Mode
ProgrammingMode (0xA5) service with sub-func. 0x01 (requestProgrammingMode) on HS/MS-CAN
MessageType=1, <[.H..]00 00 01 01 FE 02 A5 01 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 01 01 FE 02 A5 01 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 01 E5 FF FF FF FF FF FF [0012]
MessageType=2, >[.H..]00 00 07 EA 01 E5 AA AA AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 01 E5 00 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 06 43 01 E5 [0006]
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]
ProgrammingMode (0xA5) with sub-func. 0x03 enableProgrammingMode)
MessageType=1, <[.H..]00 00 01 01 FE 02 A5 03 00 00 00 00 [0012]
MessageType=2, >[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 01 01 FE 02 A5 03 00 00 00 00 [0012] TxMsgType
MessageType=1, <[.H..]00 00 01 01 FE 01 3E 00 00 00 00 00 [0012]


after programming / reading
broadcast to the bus
command 20 and the blocks will return to normal mode

ReturnToNormalMode (0x20) service
MessageType=1, <[.H..]00 00 01 01 FE 01 20 00 00 00 00 00 [0012] FramePad
MessageType=2, >[.H..]00 00 01 01 FE 01 20 00 00 00 00 00 [0012] TxMsgType
MessageType=2, >[.H..]00 00 07 E8 01 60 FF FF FF FF FF FF [0012]
MessageType=2, >[.H..]00 00 07 EA 01 60 AA AA AA AA AA AA [0012]
MessageType=2, >[.H..]00 00 06 41 01 60 00 40 00 00 00 59 [0012]
MessageType=2, >[.H..]00 00 06 43 01 60 [0006]

PS: looked at the site with your work
I think it’s not for me to teach you
you know much more than me !

PreviousNext

Return to Bosch ECUs

Who is online

Users browsing this forum: No registered users and 1 guest