STM32F750: Sixty-Four Kilobytes and a Program That Does Not Fit
Most extraction jobs have a shape that everyone recognises: open the package or use the debug port, read the array, hand over a file. This member of the family breaks that shape with a single number. It has 64 KB of internal flash and 320 KB of RAM, and it is built to run applications that are several megabytes in size.
The combination is not an oversight. It is a deliberate product decision: keep enough internal flash for the part of the program that has to be there, remove the rest, and let the customer buy external memory at whatever size the product actually needs. The consequence for a recovery is that the file read from the internal array is not the product’s firmware. It is the part of the firmware that had no choice.
What sixty-four kilobytes is enough for
Sixty-four kilobytes is roughly the size of a small bootloader plus a hardware abstraction layer plus a display initialisation sequence. That list is not arbitrary; it is exactly the set of things that must run before external memory is usable.
| what goes in internal flash | why it cannot be elsewhere |
|---|---|
| the reset vector and startup code | the core fetches its first instruction from the internal alias of flash |
| the external memory controller configuration | nothing outside the chip can be read until this runs |
| the external memory device’s own initialisation | the memory part has to be brought out of its power-on state |
| a recovery or update path | a device with a blank external memory must still be able to accept a new image |
| sometimes the whole application, on small builds | only when the product really does fit in 64 KB |
The last row is what makes the identification step necessary. Some products built on this part genuinely are small — a sensor bridge, a protocol converter, a display panel driver without much logic. Those fit. The others do not, and the difference is visible from the size and content of what is in the internal array.
Where the rest of it lives
Two external paths exist on this part and they behave differently, which matters because the recovery method differs for each.
| path | address range | execution from it | what it implies for a recovery |
|---|---|---|---|
| memory-mapped serial flash | a dedicated region for the external serial device | possible, with a cache in front | the code can be read with the same tools as internal flash, once the mapping is understood |
| external parallel memory through the flexible controller | a separate region, typically SDRAM | possible, and often the only place big buffers fit | the code may be copied there at boot and executed from RAM, leaving the original in serial flash |
The second row is the trap. A program that copies a compressed or encrypted image from serial flash into SDRAM at boot and then jumps to it leaves two artefacts: a compressed blob, and a live decompressed copy. Which one the customer wants depends on what they intend to do with it. The blob is the shippable form; the decompressed copy is easier to analyse but is a point-in-time snapshot of a device that was running.
The configuration that describes the external memory is small and highly structured: a handful of timing registers, a size and geometry word, and one or two mode settings. Those registers are a fingerprint of the memory part, and the same reasoning that recovers an SDRAM part from its timing values is set out in STM32F769 program recovery. For a product whose external device is serial flash rather than parallel memory, the equivalent reading is in STM32H725 heximal recovery, which deals with the case where that external device holds ciphertext.
Reading both halves in the right order
The order is not arbitrary, because each step depends on the previous one being understood.
Start with the internal array. It is small, it is always present, and it contains the configuration that makes the external device readable. From it, extract three things: the external controller settings, the external device’s initialisation command sequence, and the address at which the application expects to find its own code. Those three answers determine everything that follows.
Then read the external device directly. This is usually done by connecting to it rather than to the processor, because a direct read is deterministic and does not depend on the device’s own firmware working. If the external part is a serial device, the read produces a raw dump whose internal structure — page size, block size, whether there is a bad-block table — has to be understood before the contents mean anything.
Then reconcile the two. The boundary between them is not always stated anywhere: the internal image knows where it ends, and the external image knows where its own header begins, and there is often a gap of erased space between them that represents the linker’s alignment decision rather than a real boundary. A recovery that reports the gap as unprogrammed space has reported the truth about the gap and nothing about the program.
| stage | what is being read | common mistake |
|---|---|---|
| internal array | boot stage, controller configuration | treating it as the whole firmware |
| external device, raw | the application body, possibly compressed | interpreting a compressed blob as code |
| runtime copy in RAM | the decompressed, running application | reporting a live snapshot as the shipped binary |
What complete means for a split image
For a device with a single array, completeness is a length and a checksum. For a split image, it is a statement about a boundary, and that statement has to be made explicitly.
| deliverable | what it contains | when it is the right one |
|---|---|---|
| internal array only | 64 KB, with the loader clearly identified as a loader | the customer wants to understand the update mechanism |
| both images, raw | the internal array plus the external device dump, unmodified | the customer is rebuilding the device or archiving it |
| both images, reconciled | the two joined at the actual boundary with the gap explained | the customer wants a single file that can be analysed end to end |
| the runtime copy | the decompressed application as it existed when running | the customer wants to reverse-engineer behaviour quickly |
The fourth option is worth offering and worth labelling carefully. A runtime copy is the easiest thing to produce and the easiest thing to over-claim, because it reflects one execution state rather than the shipped product. Saying so in the report is what separates a useful artefact from a misleading one.
The RAM budget changes the reasoning too
Three hundred and twenty kilobytes of RAM on a part with 64 KB of flash is an unusual ratio, and it tells you something about the intended design: buffers are expected to be large and to live outside the code’s home. That has a practical consequence for a recovery. The interesting data — frame buffers, sample histories, protocol windows — is often far larger than the code, and it lives in regions whose base addresses do not follow the pattern a developer coming from a smaller part would expect. The address map that causes this confusion is described in STM32F765 heximal recovery, and the banked-flash layout of the larger members of the family is in STM32F767 firmware recovery.
FAQ
Is 64 KB really the only internal flash option on this part? On this value-line member, yes; the die exists specifically to provide a small internal array with a large RAM and a display path.
Can the external memory be read without desoldering? Often yes, through the processor’s own controller once the device is running, but a direct connection to the memory device is more deterministic and does not depend on the firmware cooperating.
What if the external device is protected? Serial flash protection is usually a status-register setting rather than a physical fuse, and its state is one of the things worth reporting because it changes what a future re-read will be able to do.
Conclusion
On a part with 64 KB of internal flash and a modern application, the internal array is the loader and the product is elsewhere. A recovery that recognises this delivers a boundary, an external device dump and an honest statement about which artefact is the shipped form; one that does not delivers 64 KB of startup code and a customer who concludes the extraction failed. The number is the first thing to look at, and it decides the shape of the entire job.