Sunrise Sunset T10

Sunset T10 User's Manual v1.40

I was given a Sunrise Sunset T10 test set for free. When I got it home, I discovered that while it powered up and passed all self tests, once it displayed the main menu, it would lock up.

When I pulled out the PCMCIA card containing the firmware and it stopped booting entirely, not even a self test, so that told me that the PC card was a linear flash card, and that CPU was booting directly from the card. I opened the unit up, and saw no obvious problems, but I noticed that it used a Motorola MC68340 CPU, similar to the MC68332 CPU in the GPS receivers I've been reverse engineering.

Because the unit seemed to function just fine up until a point, it seemed to me that the problem would be evident if I took a peek at the firmware. I hopped on eBay and bought a PCI to PCMCIA card adapter, then waited a couple weeks for it to arrive.

After some fiddling around, I finally got the linux MTD driver to see the 2 megabyte PCMCIA card when I realized I had to tell the modprobe command that it was ROM, not flash. Then it was a matter of just dd'ing the contents of the card to a file.

My usual flow for reverse engineering firmware is to first run the strings command on it. If I see any human readable strings, it's a good indicator that at least some of the card is clear text. I could see strings in my dump, so I knew I had something useful.

I loaded up the file in a hex editor, the first 1k looked like a 68k vector table, so the next stop was Ghidra. Once loaded in Ghidra, I noticed a big chunk of string data at the end of the file. Upon closer examination, I could see that it looked symbols. Back in the hex editor, I could see it was definitely symbols, and it appeared to be a symbol table in ASCII format.

What's weird about the symbol table is that it contained two 'dislocations', it seems like the table was generated, then two functions were modified, causing the table after those points to be offset. I wrote some code to read in the table, sort it by address, then apply corrections based on trial and error of fitting the symbol table to defined functions. With the symbol table applied to the code, I ended up with a very easy to follow disassembly, easily the easiest I've worked with so far.

When I bought my HP1670D logic analyzer, it came with a PCMCIA probe card, which sits between a PCMCIA card and its socket, and gives access to all of the signals. I used this to intercept all accesses to the PCMCIA card and feed them into my logic analyzer.

The catch with using this technique is that it appeared that the bus control logic of the T10 turned off the address and data busses when the internal RAM was being accessed, so I could only see activity happening when the CPU was interacting with data stored in flash. But I could see the address where the fetches stopped happening, but strangely it was in the middle of an instruction.

I slept on it, re-worked my triggering setup, and then I was able to see that after trying to read half an instruction, the CPU was trying to read from a low address just before it died. Then I realized how it was able to die mid-instruction: the CPU32 is pipelined. Looking at the disassembly, I could see that the CPU was fetching a value from the battery backed NVRAM, and using it as an offset in a table lookup. The NVRAM was corrupt, so it was providing a bad value (that I couldn't see) to the CPU, the CPU was calculating an address, which caused an address violation, which caused the CPU to try to jump to an address in the exception table.

From the disassembly, I could see that there was no way to clear the NVRAM by holding down a key at boot. But I could see that if the unit detected that the version number stored in NVRAM was missing or didn't match what was in flash, it would proceed to zero out the entire NVRAM block, so I knew it would be fine to erase it. So I temporarily desoldered the battery to clear the NVRAM. When the unit came back up, it did what I expected: it detected that the version number was missing, zeroed out the NVRAM, and proceeded to boot like normal. After that the unit worked just fine.

Firmware Version S2.21g Image & Ghidra Disassembly