cancel
Showing results for 
Search instead for 
Did you mean: 

Is the ROM bootloader source available somewhere?

Matthijs Kooijman
Associate III

I'm planning to use the built-in ROM bootloader in an STM32F4 chip for DFU uploads and having a hard time figuring out how it works exactly (in particular what pins it initializes at what moment in the boot process, and what I need to do externally to prevent it from going into e.g. SPI or UART mode). The documentation is missing some details (and experiments also give me puzzling results), so I'm looking for some more specific insight in the workings of this bootloader, which would be perfectly solved by looking at the source code.

I've read some earlier related posts, and I suspect that the sources are not currently available, but maybe someone at ST will see this as a request to change that? I would think there will not be any secrets in their bootloader sources, but it would make the bootloaders (and thus their hardware platform) a lot more usable.

Note that I realize that the ROM bootloader is not perfect and might not be a good basis for a custom bootloader, but that is not my goal (my goal is to understand and use the ROM bootloader). I also realize that the bootloader is in ROM and cannot be modified.

I also realize that using a custom bootloader in flash is also a commonly used option, but I'd prefer to use the builtin one (since that can certainly not be erased, and simplifies production).

I noticed @Community member​ mentioning in this topic that you can read back the compiled bootloader from ROM and disassemble that, which would also be helpful (but a lot harder to read, of course). He mentions his "own annotated listings", but without a link it seems. I wonder if there is any repository of such listings or dumps? If not, anyone aware of some tutorial on how to generate them? Though I guess it's a matter of dumping memory through SWD and then disassembling with something like `objdump`?

15 REPLIES 15

> Though I guess it's a matter of dumping memory through SWD and then disassembling with something like `objdump`?

Instead of objdump it's better to use a proper reversing tool like Radare2 (with Cutter GUI if you would like), or Ghidra. They can even help to get a decompiled C code (not the original, of course). Try to get help in reverse engineering communities.

IANAL, but before actually using the disassembled/decompiled code of ST's proprietary binaries I advise you to explore the legality of doing that.

Uwe Bonnes
Principal III

You present no good reason to decompile. System bootloader is described in AN2606 and there are a lot of programs that use DFU successful with STM32, to name dfu-utils. You put some test for some magic in some RAM that is not yet erased and if you see that magic, erase the magic and jump to the bootloader. In your user program, have some command to set that magic and to a warm reset. That is all.

Matthijs Kooijman
Associate III

> Instead of objdump it's better to use a proper reversing tool like Radare2 (with Cutter GUI if you would like), or Ghidra.

Thanks, I'll have a look at those.

> You present no good reason to decompile. System bootloader is described in AN2606 and there are a lot of programs that use DFU successful with STM32, to name dfu-utils.

Ok, let me make some of the questions I have (and which I cannot find answered in AN2606) explicit. I'm looking at the STM32F401xE

  • What are the exact pin modes used by the bootloader? Table 46 in AN2606 lists them, but e.g. for SPI it says "push-pull pull-down mode". What does that mean? "push-pull" means "output" to me (so drive low or drive high), so what good would a pull-down do? And the same mode is listed for all SPI pins, while some of them would need to be input and some output?
  • When are pins initialized exactly? e.g. to detect a sync byte on the UART, the bootloader only needs to enable its RX pin, but maybe it also enables it TX pin (i.e. set to output) right away? Or maybe only after receiving the sync byte on RX? There is a note in the changelog for the STM32F105xx/107xx (section 14.3.4) that suggests that for that chip, the TX pin was originally initialized right away, but this was later changed to initializing it later to prevent sinking high currents when the TX pin is also used for USB. But other than that note, the pin list for those chips have no indication of this, and the documentation for my STM32F401xE has no mention either, but does have the same pin shared between TX and VBUS. The bootloader version number is newer, so maybe it has the "new" behaviour?
  • Is the NSS pin used for SPI active-high or active-low? The latter is more common, but the docs say there is a pull-down (confirmed by measurements), so that would suggest that it is active-high (so the SPI slave is inactive by default and can be made active by driving NSS high). However, figure 4 on page 32 shows the SPI hardware connection and shows tying NSS to GND to make/keep the SPI slave active, so that suggests active-low. But then how to keep the slave *inactive*? Tie the pin high? But I also want to use the pin for GPIO when the bootloader is not active, so then I'd rather use a pullup resistor (but it would need to be small enough to compete with the builtin pulldown...).
  • How does the bootloader decide what protocol to use exactly (e.g. when does it *stop* trying different protocols and will it select one)? The flowchart in figure 31 says vague things like "USB cable Detected" (but there is no VBUS connection, so cable insertion cannot be detected AFAICS. Maybe this means "USB reset" or "USB enumeration" instead? Or "SPIx detects Synchro mechanism", which I guess means receiving the "Syncrhonization byte" defined in AN4286, or does it happen when the NSS pin is pulled low already?

I guess that clarifying these things in the official docs would also be great and a lot easier than having to read the source code. However, being able to read the source code would make it possible to also answer these questions (and more, these are just the things that I remembered wondering and needing recently, I can imagine that for different usecases, other details can be important).

Does this help clarify the background of my question?

> and there are a lot of programs that use DFU successful with STM32, to name dfu-utils. You put some test for some magic in some RAM that is not yet erased and if you see that magic, erase the magic and jump to the bootloader. In your user program, have some command to set that magic and to a warm reset. That is all.

That part is actually already clear, I've made the "warm reset" part and dfu-utils upload work. However, I need to make this reliable and ensure the bootloader 1) does not jump into e.g. SPI mode accidentally, breaking USB uploads and 2) does not put some pins in output mode that would cause a short-circuit or overcurrent condition. Both of these I can fix by careful pin selection and PCB design, but then I do need to know what the constraints are exactly.

To more completely quote myself, I said "Created my own annotated listings here", which basically means I did it myself, it took effort and it is work product. Publishing other people's work tends to get into a more complex area, whereas interfacing, vulnerability testing, and due-diligence tend to be broadly acceptable use cases.

One could perhaps use objdump or fromelf, but these are a bit like Butter Knives, I use instruments which are a lot sharper, which I fashioned myself. The use of simpler/prolific tools tends to be improved significantly with post-processing to reformat to a preferred style with flow and interaction paths identified.

I can also sight-read code, so it doesn't matter much if it is C, Assembler or whatever.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I don't know, the documentation from ST is seriously deficient and not up to date. There's almost always a good reason to understand what the micro-controller is doing in any given circumstances.

The OP already indicated that it is the undocumented and nuanced behaviour that is problematic. Things like post-reset pin sensitivity and control flow, which can render a design difficult to program.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Uwe Bonnes
Principal III

Did you have a look at the Bootloader selection flows presented in AN2606. It also clearly tells what facilities are involved. But if you want full controll over the bootloader, write your own or look on the web for existing ones.

> To more completely quote myself, I said "Created my own annotated listings here", which basically means I did it myself, it took effort and it is work product.

That makes sense. I think I was hoping that "here" in your sentence was supposed to be a link, but reading it as "here in-house" also makes sense. I understand that publishing that might not be trivial. Thanks for you addition, though :)

Yeah, I have looked at the selection flow, but it is lacking in detail (as indicated in my reply above), and also does not paint the whole picture (it does not detail when pins are initialized, for example). Also, I am not looking for full control over the bootloader, I'm looking the understand the builtin one so I can use it without problems later on.

While AN2606 does provide some level of detail, I find it to be lacking and incomplete. It really doesn't help to identify where all the land mines are buried, and stuff in general is not fully disclosed and subject to change.

The more pins/functionality they add, the more difficult it is to avoid clashing with that at a board level, especially with the lack of alternate-function mapping abilities of the part. Kind of would like to have USART1 and USART3 attached to things that might squawk at startup.

The behaviour of new devices to test and jump into FLASH applications, being particularly unhelpful. More considered ROM Boot Loaders provide multiple entry points and APIs. In such a scenario a boot could be directed to use only a specific interface/pins.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..