The thing that annoys me most about the ECU in my car is that it gives barely any debugging information about sensors and states. It's an older car so some of the sensors started getting a little wacky, but which ones? Fast forward a week and I had decided I needed to pull the code off the ECU to see how it works, then add a few functions of my own. There are a few businesses out there that reflash ECUs for performance increases and such, so if they can do it so can I.
I started by grabbing an ECU for my year and model of car from a junkyard, and opening it up.
A quick glance shows that it's very simple: a C167 MCU, which loads its code from an Am29F400B flash at boot. The C167 is a great device for cars, as it has a ton of PWM channels and speaks CANBUS natively, and even includes the ability to
load code via CANBUS. I was able to quickly find the
datasheet and
debugging hints documents, as well as a
datasheet for the flash itself. Clearly, my next course of action was to yoink the flash and read it (note that in the above pics, I've already desoldered it from the board).
I hacked up a board design to give me easy access to the pins, and cut it using the mill:
I did my math right and it came out great the first time. I had quite an internal debate about reading the data though- the elegant way to go about it would have been to write a general FPGA memory reader-writer that would also allow me to do passive memory snooping (ie, latch on address changes and record both the address and data value), but I decided to focus on one project at a time and just wrote a few lines of C for an Atmega board I had handy:
It worked nicely! I need to spend some time mapping out the IO addresses, but at first glance, the bootloader has an amusing tamper-protection scheme. The first block of code on the flash loads data into RAM from farther down the flash itself... but adds 1 to each value. Thus, to recover the original instructions, all I had to do was decrement each value by one and pass it into the disassembler again. Epic.