The Prusa Mini+ Buddy board ships with a bootloader pre-flashed at the factory.
When compiling the firmware source code from this repository, the bootloader is downloaded in binary form by utils/bootstrap.py as part of the build process, from this URL:
https://prusa-buddy-firmware-dependencies.s3.eu-central-1.amazonaws.com/bootloader-mini-1.0.0.zip
This ZIP file contains a 128KB binary file named bootloader.bin:
Archive: bootloader-mini-1.0.0.zip
Length Date Time Name
--------- ---------- ----- ----
131069 2019-11-08 07:09 bootloader.bin
212 2019-11-08 07:09 __MACOSX/._bootloader.bin
--------- -------
131281 2 files
The source code which generates this binary file, which contains executable ARM code, does not seem to be available anywhere in Prusa's GitHub repositories. This bootloader is distributed with the Prusa Mini+, in the flash memory on the ARM chip on the Buddy board, alongside and packaged together with the rest of the firmware, which of course is based on Marlin. It is also distributed in binary form, similarly packaged with Marlin, as part of the official firmware file downloadable from Prusa's website (https://www.prusa3d.com/drivers/).
The entire project is a covered work under the terms of the GPL v3 license, as it is based on Marlin which is also GPL v3. I believe that Prusa is required to supply the complete source code for the entire firmware, including the bootloader, because it is packaged together in the distribution media which Prusa itself distributes, to form a larger program. Therefore, in order to comply with Marlin's source code license, I believe Prusa is required to supply the source code for the bootloader.
I hereby request Prusa make available the source code for bootloader.bin.
It is sad that prusa does not comment on this :-(
They might think that as long as they do not link the bootloader against the firmware they don't need to provide the source. One could argue that the bootloader and the firmware are separate executables that are side by side in the chip and therefore different software. If that holds then they would not be required to publish the source. But I'm not a lawyer.
But they also release the 3d files of the plastic parts and so much other stuff that they would not need to release. So why not the bootloader? Maybe they have a good reason?
If you do $ strings bootloader.bin you get all the text contained in the binary file.
strings.txt
So the Bootloader can do an update from USB. And there is this string
Developer firmware
Maybe they don't want everybody to know how to create a Developer firmware ?
Next we can do this
$ arm-none-eabi-objdump -D -bbinary -marm bootloader.bin -Mforce-thumb > output.s
that gives us a disassembly.
output.s.zip
Looking through that could take some time. A help could be Radare2 like this
$ r2 -a arm -b 16 -m 0x08000000 -w bootloader.bin
To understand how that works take a look here: https://radare.gitbooks.io/radare2book/content/first_steps/intro.html
So now who will be first to understand how the Developer firmware feature works?
They might think that as long as they do not link the bootloader against the firmware they don't need to provide the source.
GPLv3 is quite clear on this topic:
- c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply ... to the whole of the work, and all its parts, regardless of how they are packaged.
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
The first paragraph clearly applies. Prusa might argue that the combination of the bootloader and the main program is just an aggregate, but the license clearly states that it is not an aggregate if they are combined to form a larger program in or on a storage or distribution medium - and clearly the flash memory of the STM32F407 is a distribution medium. Furthermore, Marlin includes bootloaders, so the Prusa bootloader is "by its nature an extension of the covered work".
Developer firmware
Good find. Some disassembly reveals the "Developer firmware" message is activated if the 64-byte signature (normally produced from Prusa's private key, and verified using the public key in the bootloader) is filled with 0xFF. The signature is flashed at the start of the firmware image, at memory offsets 0x8020000 - 0x8020040. This is easy to arrange for with a small modification to the build script (specifically pack_fw.py, change 'sig = bytes(64)' to 'sig = b'\xff' * 64'). I'm not sure what the practical implication of this is. I already broke the appendix so I can't determine whether it allows the normal intact-appendix signature check to be bypassed or not, but it's a possibility. It may also bypass the SHA hash check.

Practically speaking, I'm currently trying to get Klipper running, and it would be a much easier task if I could see how the bootloader works. Another reason I could use the source is that the bootloader that shipped on my Mini+ was v1.1.0, but the binary bootloader downloaded by the build script is an old version v1.0.0; I've already accidentally downgraded and don't have a copy of the v1.1.0 bootloader binary to replace it, let alone the source.
I hope they take care of this matter quickly, otherwise it may be necessary to escalate to their legal team, or the great man himself.
I used a original BBF file and changed the first 64 Bytes to 0xff. I could not flash that image. I did not see the Developer Firmware message.
I have bootloader 1.1.0 and did not break the appendix.
Could you share the BBF file that got you to "Developer firmware" ?
Regarding Klipper: The bootloader will most probably only shift the start address of the firmware and the address of the Vector table. You can probably get both from the Lionker file used to compile the Prusa Firmware. With those changes it should be possible to put the Klippy Firmware into a BBF file and have it flashed and run as Develeoper firmwware.
But the you will need to repeat that with every Klipper update that chenges the firmware,...
Or as you have already broken the apendix, jsut use the SWD interface, get rid of the Bootloader and flash the Klipper firmware using SWD.
You might want to sdisassemble the display unit and remove the foil from the screen, that will also remove that green thing in the bottom left corner.
I could not flash that image.
That confirms breaking the appendix (or lifting BOOT0 etc.) is still necessary to open things up, even when uploading "Developer firmware".
Could you share the BBF file that got you to "Developer firmware" ?
Don't have it handy but it was identical to what you created by patching the first 64 bytes.
DFU via USB seems more reliable than the stock bootloader (slow and occasionally ignored BBF updates on the USB drive). I added a cable to extend the 2-pin header outside the box, I just add the jumper and reset, then use dfu-util. SWD debugging is working too using OpenOCD.
I have Klipper running - bootloader offset was the issue. Foil on the screen is to protect it from the appendix-shaped PCB projectile flying around the room ;)
I could not flash that image.
That confirms breaking the appendix (or lifting BOOT0 etc.) is still necessary to open things up, even when uploading "Developer firmware".
Not so fast. I used a different Bootloader than what you tested with. So it might be a new feature in the 1.1.0 version. They might have changed the Developer Firmware signature to something else or removed the feature completely.
You can test if the "appendix" is the issue by connection BOOT0 and SWDIO to GND. That is all the appendix does.
Now I also want to see the Source code of the Bootloader,....
@JohnnyDeer What is the Prusa position regarding GPL and the Bootloader?
GPLv3 is quite clear on this topic:
- c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply ... to the whole of the work, and all its parts, regardless of how they are packaged.
A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
The first paragraph clearly applies. Prusa might argue that the combination of the bootloader and the main program is just an aggregate, but the license clearly states that it is not an aggregate if they are combined to form a larger program in or on a storage or distribution medium - and clearly the flash memory of the STM32F407 is a distribution medium. Furthermore, Marlin includes bootloaders, so the Prusa bootloader is "by its nature an extension of the covered work".
Can you point us to the Bootloader repository, or does Prusa have a different view on the license terms?
Hey @matthewlloyd and @JustAnother1,
Thank you for your patience regarding this issue. To answer the primary question here: the bootloader is a separate project from the Buddy firmware. The Buddy firmware is in no way dependant on it and is fully functional without it. The bootloader isn’t part of the Buddy firmware, and we don’t distribute it as part of the BBF files on our website (as mentioned in the first comment). Therefore, we believe that seen from the point of the GPLv3 license, the firmware and the bootloader form an aggregate, and we are not obliged to release the bootloader’s source code. In the same way, the license does not require us to open source the source code of the stock bootloader pre-flashed by STMicroelectronics.
But hey, that being said, we are planning to open-source the bootloader :slightly_smiling_face:. Even though it is not a current priority, we are taking steps towards making it eventually happen.
So now who will be first to understand how the Developer firmware feature works?
Don’t want to spoil the fun, but I have to say that there is no hidden “Developer Firmware” feature. The “Developer firmware” string you found in the disassembly appears when the firmware isn’t signed. And to flash an unsigned firmware, you have to break the appendix first. So again, no hidden feature here – even all the printers at our offices have broken appendixes.
but the binary bootloader downloaded by the build script is an old version v1.0.0; I’ve already accidentally downgraded and don’t have a copy of the v1.1.0 bootloader binary to replace it
Thanks for pointing this out! I just made a note to update the bootloader there.
Thank you for your patience regarding this issue. To answer the primary question here: the bootloader is a separate project from the Buddy firmware. The Buddy firmware is in no way dependant on it and is fully functional without it. The bootloader isn’t part of the Buddy firmware, and we don’t distribute it as part of the BBF files on our website (as mentioned in the first comment). Therefore, we believe that seen from the point of the GPLv3 license, the firmware and the bootloader form an aggregate, and we are not obliged to release the bootloader’s source code. In the same way, the license does not require us to open source the source code of the stock bootloader pre-flashed by STMicroelectronics.
One might argue that the Prusa Bootloader and the Prusa Firmware share the same medium(Flash) but the ST Bootloader is in ROM, but I'm not a lawyer.
But hey, that being said, we are planning to open-source the bootloader slightly_smiling_face. Even though it is not a current priority, we are taking steps towards making it eventually happen.
It would be great if you could post the link to that (once it happened) here, so that others with the same question can find the link.
but the binary bootloader downloaded by the build script is an old version v1.0.0; I’ve already accidentally downgraded and don’t have a copy of the v1.1.0 bootloader binary to replace it
Thanks for pointing this out! I just made a note to update the bootloader there.
A link to the binary would also be appreciated (for the same reasons).
Thank you for looking into this. Like I said before Prusa is opening up so much,also opening up the mechanical (printed) parts of the printer, so not opening up the Bootloader sounded wrong. I'm happy that this will be solved. Keep up the great work!
but the binary bootloader downloaded by the build script is an old version v1.0.0; I’ve already accidentally downgraded and don’t have a copy of the v1.1.0 bootloader binary to replace it
Thanks for pointing this out! I just made a note to update the bootloader there.
A link to the binary would also be appreciated (for the same reasons).
Here it is :) https://github.com/prusa3d/Prusa-Firmware-Buddy/pull/1482
Many thanks to Prusa for replying to this thread.
we don’t distribute it as part of the BBF files on our website
I stand corrected, and agree that the bootloader is not distributed in the BBF downloaded from Prusa's website. It is, however, distributed on the board's flash. It is also clearly intended to be linked with it as part of the process in utils/build.py.
The Buddy firmware is in no way dependant on it and is fully functional without it... the firmware and the bootloader form an aggregate.
This is not entirely accurate. The bootloader and Buddy firmware communicate bidirectionally via shared memory. Using shared memory to communicate is generally considered dynamic linking, which does make programs a combined work.
We can only see one side of the communication since the bootloader is closed source. At the very least we can see that the firmware communicates update mode flags (set via the GUI menu) to the bootloader, and the bootloader communicates the status of the appendix to the firmware. Perhaps there is more. Here are some code excerpts:
https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/master/src/common/shared_config.h
typedef struct {
uint8_t fw_update_flag;
uint8_t model_specific_flags; // ~ "reserved1" originally
...
} data_exchange_t;
/* to exchnage data between bootloader and application */
/* this section is filled with zeros on each application start */
.boot_fw_data_exchange 0x20000000 :
{
_sboot_fw_data_exchange = .; /* global symbol at start */
KEEP (*(.boot_fw_data_exchange))
. = ALIGN(4); /* allignment is important as 4 bytes are written to zero at once in startup code*/
_eboot_fw_data_exchange = .; /* global symbol at the end */
} >RAM AT> FLASH /* AT> FLASH added to avoid the binary size increase*/
bool appendix_exist() {
const version_t *bootloader = (const version_t *)BOOTLOADER_VERSION_ADDRESS;
if (bootloader->major >= 1 && bootloader->minor >= 1) {
return !(ram_data_exchange.model_specific_flags & APPENDIX_FLAG_MASK);
} else {
...
void sys_fw_update_on_restart_enable(void) {
ram_data_exchange.fw_update_flag = FW_UPDATE_ENABLE;
}
But hey, that being said, we are planning to open-source the bootloader 🙂. Even though it is not a current priority, we are taking steps towards making it eventually happen.
This is very good to hear. I do hope given the above, that Prusa honors the open source community and respects the terms of Marlin's GPLv3 by releasing the source code for the dynamically linked bootloader as soon as is reasonably possible.
Here it is :) #1482
Fantastic - thank you so much for uploading the latest version. We are all very excited about the upcoming release of the i3 MK4 and XL.

@matthewlloyd what you describe only applies, if the dynamically linked software is under gpl license. then you are correct, the linking software has also to comply with the gpl.
the other way around makes no sense whatsoever, because it would leave people unable to dynamically link non gpl libraries in their gpl projects.
i can not force, say microsoft, to open source their proprietary library by dynamically linking it in my gpl project, you see my point, right?
i can not force, say microsoft, to open source their proprietary library by dynamically linking it in my gpl project, you see my point, right?
The GPL specifically carves out an exception for "System Libraries", which applies for example to Microsoft's proprietary libraries, but does not apply here because a bootloader with bidirectional communication via shared memory does not meet the definition of a System Library. You can read the GPL FAQ here for more information: https://www.gnu.org/licenses/gpl-faq.html#SystemLibraryException.
The incorrect assertions in the rest of your comment are addressed in the GPL FAQ here, and in other places: https://www.gnu.org/licenses/gpl-faq.html#MoneyGuzzlerInc. In short, the GPL does not allow GPL-covered software to be linked (dynamically or otherwise) with closed source libraries, except for the System LIbrary exception as described above, and for aggregates, which this is not (see https://www.gnu.org/licenses/gpl-faq.html#MereAggregation).
Most helpful comment
Hey @matthewlloyd and @JustAnother1,
Thank you for your patience regarding this issue. To answer the primary question here: the bootloader is a separate project from the Buddy firmware. The Buddy firmware is in no way dependant on it and is fully functional without it. The bootloader isn’t part of the Buddy firmware, and we don’t distribute it as part of the BBF files on our website (as mentioned in the first comment). Therefore, we believe that seen from the point of the GPLv3 license, the firmware and the bootloader form an aggregate, and we are not obliged to release the bootloader’s source code. In the same way, the license does not require us to open source the source code of the stock bootloader pre-flashed by STMicroelectronics.
But hey, that being said, we are planning to open-source the bootloader :slightly_smiling_face:. Even though it is not a current priority, we are taking steps towards making it eventually happen.
Don’t want to spoil the fun, but I have to say that there is no hidden “Developer Firmware” feature. The “Developer firmware” string you found in the disassembly appears when the firmware isn’t signed. And to flash an unsigned firmware, you have to break the appendix first. So again, no hidden feature here – even all the printers at our offices have broken appendixes.
Thanks for pointing this out! I just made a note to update the bootloader there.