Posts Tagged ‘recover microcontroller protected firmware’
ATmega644P: The Second USART Is a Way In
A 40-pin AVR with 64 KB of flash usually has one serial port, and by the time a product ships that port is doing something important — a display, a host protocol, a radio module. Anything you want to say to the device has to share the wire with traffic that was designed without you in mind, which is why so much AVR work ends up on the programming header instead of the application interface.
The ATmega644P is different in a way that is easy to overlook when reading a datasheet and impossible to ignore once you are holding a board. It has two independent USARTs. The second one is frequently initialised in the vendor’s firmware even when the final product does not use it, because it existed during development, or because a factory fixture used it, or because the same code base serves several products and only one of them connects the pins.
What a second port buys you
Two serial channels means the application keeps its own conversation and a second conversation becomes available. If the second USART is brought out to a pair of pads, a header, or a test point, then read and write access to the running firmware exists without touching the ISP pins at all.
| Situation | One USART | Two USARTs |
|---|---|---|
| Application port in use by a host | No free channel | Second channel available if brought out |
| Bootloader waits on UART0 | No free channel | Wrong port for you, but the first is now documented |
| Factory test pads left on the board | Not usable unless the application idles | Usually still listening for a fixture command |
| Debug printf compiled out of release | Gone | Sometimes still present on the unused port |
The practical benefit is not that a second port is faster. It is that a second port is often idle, and an idle port does not fight you for timing.
Finding out whether the second one is alive
The measurement is simple and does not require the firmware image. Power the board normally, attach a serial adapter to the second port’s pins at the supply’s logic level, and listen. Then send a newline, a couple of 0x55 bytes, and a question mark. Devices that were built with a fixture protocol frequently answer something, even if the answer is an error message, and an error message is a signature that identifies the protocol.
Do this at the baud rate the clock actually produces, not the one on the schematic notes. A part running from its internal 8 MHz oscillator divided by eight is at 1 MHz, and a nominal 9600 baud setting will be wrong by whatever error the divider introduces. Sweeping the common rates at each plausible clock is a small, bounded search: it either produces readable text or it does not.
Two rules keep this from wasting a day. First, do not assume the pin order — swap TX and RX once before concluding anything. Second, if the port is shared with another function through a multiplexer or a jumper, find the selector before you decide the port is dead.
What to do with a channel once you have one
An open channel changes the shape of the job. Instead of extracting an image and then guessing what it does, you can ask the running firmware questions.
- Read the device signature and the fuse bytes through bootloader commands, which confirms what the part actually is rather than what the silkscreen claims.
- Request a page of flash and compare it against a second unit, which separates shared code from per-unit data.
- Trigger the vendor’s own self-test, which often exercises the peripherals and reports which are populated.
None of that requires the lock bits to be cleared, which is the point. A bootloader that was written to accept commands over a UART rarely checks whether the flash is locked, because the lock bits exist to stop reads through the programming interface, not to stop the bootloader from doing its own job.
When the port is not there
Boards that never brought the second USART out still sometimes leave the two pins configured as a USART with the transmitter enabled. That is measurable: the TX pin idles high with a faint periodic activity if the firmware sends anything at all, and it reads as a push-pull output rather than a floating input. A scope on the pin answers the question in ten seconds.
If the pins are used for something else, they will be switching with the application’s rhythm, and the idea is closed. That is a normal outcome and worth recording, because it tells you the vendor was not leaving a door open and the work has to go through the programming interface or through the array itself.
The part-specific detail that matters during extraction
The 644P organises flash into 256-byte pages and supports read-while-write, which means the boot section can be programming the application section while the CPU executes from the boot section. That is useful to the firmware and unhelpful to a reader: a dump taken while a page write is in progress can return a page that is half old and half new.
The defence is not clever, it is procedural. Read the whole array, then read it again, and compare. A page that differs between two consecutive passes is a page that was being written; it is not a corrupted chip and it is not a reason to reach for the erase command.
Related reading
- ATmega644 page buffers and why dumps come out ragged — the read-while-write behaviour in more detail.
- ATmega644PA and the fuse that removes your way in — what happens when RSTDISBL is programmed.
- ATmega164 and the boot section guard bits — the same peripheral set in a smaller package.
FAQ
Does a second USART mean the flash is readable? No. It means a command channel may exist. Whether the firmware will hand over memory through that channel depends on what the bootloader was written to accept.
Can the lock bits be cleared over a serial bootloader? Some bootloaders implement a chip erase command, which clears the lock bits and the program together. That is destruction, not recovery, and it should never be issued before the image has been secured.
Why would a vendor initialise a port the product does not use? Shared code bases, factory fixtures, and leftover debug paths. In practice all three are common, and all three leave the port listening.
Is the second USART present on every 644 variant? It is present across the 644 family. Confirm against the specific orderable code before relying on pin positions, because package options differ.
Conclusion
The second USART on this part is not a feature you exploit so much as a door that vendors leave unlocked. Look for it before committing to a destructive route: two pins, a level shifter, and a baud sweep either open a conversation or close the question in an afternoon.