MBED_APP_START incorrect

Hi. Using Mbed Studio and Mbed 6.2.0

Adapting the bootloader example, I find that the linker is given the command MBED_APP_START=0x18000, even though my bootloader binary is built for a size of 0x28000 (and I’ve tried other values).
The map for the bootloader shows this:
Load Region LR_IROM1 (Base: 0x00000000, Size: 0x0001017c, Max: 0x00028000, ABSOLUTE)

The compiler shows :slight_smile:Using ROM regions bootloader, application in this build.
Region bootloader: size 0x18000, offset 0x0
Region application: size 0x68000, offset 0x18000

Where does it get this WRONG value from?

Robert

Hello Robert,

I’m not sure I fully understand your concern. Based on what you wrote I think the actual size of your boot-loader seems to be 0x0001017c. But because flash ROM sectors must have been erased prior to being programmed the application program must start on the following sector and the size of the boot-loader is increased accordingly (if the application was put on the same sector the boot-loader would be deleted before flashing the application program). So my guess is that the next sector (after 0x0001017c) on your target starts at 0x18000 that’s why the size of the boot-loader was increased to 0x18000 and the MBED_APP_START=0x18000. To figure out the sector layout on your target check the datasheet or use the Flash IAP.

Best regards, Zoltan

In the bootloader code itself, mbed provides POST_APPLICATION_ADDR with the value 0x28000, which is where it then tries to load and execute the actual application. The linker wants the application to be at 0x18000!!!

The bootloader itself stays in flash up to the maximum.

The linker calculates the POST_APPLICATION_ADDR based on the boot-loader size and sector layout on the given target. So try to modify the POST_APPLICATION_ADDR in the boot-loader via a mbed_app.json file as follows:

{
    "target_overrides": {
        "*": {
            "target.restrict_size": "0x18000"
        }
    }
}

My point is that I have got
“target.restrict_size”: “0x28000”,
in my bootloader json, which is why it produces POST_APPLICATION_ADDR = 0x28000, then the code will call
mbed_start_application(POST_APPLICATION_ADDR ),

but Mbed has linked the application for a different address!

What is your target board?

I have 3 ! but that was an LPC 1768

(also have ublox c027 and DISCO L496AG

After the build completes, the build system creates two binary images in the BUILD/<TARGET_NAME>/<TOOLCHAIN_NAME> directory: <project-name>.bin and <project-name>_application.bin . <project-name>.bin is the padded bootloader (used for combining with applications). <project-name>_application.bin is the original unpadded bootloader.

When building the application with the bootloader are you sure that you set the target value bootloader_img in mbed_app.json to the file path of the padded bootloader image and not the original unpadded bootloader?

  1. I build the bootloader
  2. I copy the bootloader binary to the application workspace
  3. mbed_app.json:
    “target.bootloader_img”: “bootloader/mbed-os-example-bootloader.bin”

Is that not the process?

Yes, that’s the recommended process. The binary name seems correct (doesn’t have the “_application” in the name. But if you copied the bootloader binary to the application’s root folder then try to use:
“target.bootloader_img”: “mbed-os-example-bootloader.bin”

Now I’m confused by your last two (contradictory?) messages.
When I build the bootloader itself, what do you mean by the padded and unpadded version? The binary I have been copying to the application workshop (in subdirectory bootloader) is mbed-os-example-bootloader.bin.

The Building the bootloader section in Getting started with bootloader on mbed OS bootloader example says:

After the build completes, the build system creates two binary images in the BUILD/<TARGET_NAME>/<TOOLCHAIN_NAME>` directory:

  • <project-name>.bin and
  • <project-name>_application.bin .

<project-name>.bin is the padded bootloader (used for combining with applications).
<project-name>_application.bin is the original unpadded bootloader.

NOTE: I formated the quoted block above a bit to make it neater.

Thank you for clarifying that. That is what I have been doing all along.

So now back to the original question, why does Mbed not pick the correct value from the padded binary and use for MBED_APP_START?

I have built a simple bootloader:

#include "mbed.h"

#if !defined(POST_APPLICATION_ADDR)
#error "target.restrict_size must be set for your target in mbed_app.json"
#endif

FlashIAP flash;

int main()
{
    printf("Launching the bootloader\r\n");
    printf("About to start the application at 0x%x\r\n", POST_APPLICATION_ADDR);
    mbed_start_application(POST_APPLICATION_ADDR);
}

using mbed_app.json:

{
    "target_overrides": {
        "*": {
            "target.restrict_size": "0x28000"
        }
    }
}

It printed the following message when running on an LPC1768:

Launching the bootloader
About to start the application at 0x28000

To figure out the programs’ size I converted both binaries (padded and not padded) to hex files using the arm-none-eabi-objcopy utility. Then I run the arm-none-eabi-objdump -x utility and it displayed the same size for both programs (padded and not padded):

Idx Name          Size      VMA       LMA       File off  Algn
  0 .sec1         0000f250  00000000  00000000  00000000  2**0

So my conclusion is that Mbed doesn’t pad the binary when building the bootloader and the linker is using the not padded size to build the application program.

Hi both,

I had probably an similar issue, when I played with the bootloader on Nucleo-F429ZI with a SD card on MbedOS 5.15 few months ago. My understanding is as follows.

The target.restrict_size aka MBED_APP_START can not be set to any value, it must be set to a value what corresponding to the bootloader size and also size of memory sector.
In the followed application where will be the bootloader used, it will calculated the size of the bootloader before compilation and according to its size and memory sectors it will be set the MBED_APP_START for the application.

Lets say, for my Nucleo I can use these possible values as the restrict_size (memory sectors) - 0x10000 / 0x20000 / 0x40000.... And when I will use Zoltan’s simple bootloader then I can not use the value 0x20000 but 0x10000 because that will be calculated in the application program, according to size of the bootloader.
When I put some APIs in to the bootloadrer (SD card, KVStore and so on) the size of bootloader will be increased and then also the result of the calculation will large. So the value 0x20000 is necessary.

My issue was I put wrong value into the target.restrict_size.

  1. I used the number what was not in alignment of memory sectors like 0x15000
  2. I used larger number what was not needed and also was not calculated by followed application program.

BR, Jan

I don’t know the internals of Mbed but it seems to me that either the build for the bootloader should produce a large image which the application build should use to calculate the load point, or that the binary itself contains that information. I know that elf formats do that.

Is this going to be fixed?

Thank you Jan for sharing your experience! It confirms what I assumed in my first post. It would be nice if Mbed Team could update the Mbed bootloader documentation and the related example according to your explanation. That would certainly save us, users, lot of frustration and time.

In the past the bootloader used to be padded as stated in the documentation. So the size of the binary to be used for combining with applications was inflated to the size set in the mbed_app.json by appending zeroes. But that has been apparently changed by Mbed developers without modifying the documentation.

There needs to be an automatic way for this to work. It isn’t good enough to manually decide how big the bootloader is then rebuild. In fact it make sense to choose a value larger than the actual binary to allow for expansion as Jan said.