Boaz
Boaz

Reputation: 21

load time base address cortex-m3 bare metal

I'm working on a project on a cortex-m3 CPU with bare-metal environment. Due to software upgrade needs the executable image on the CPU can be in one of two addresses in the flash memory which presents a problem. The start address of the image is known only at load time and not during static-linkage. I'm not too sure but I think this doesn't really qualify as dynamic loading but I could really be mistaken here as I'm no expert on this. Is there a way to compile and link the image in a way it's base address can be given only at load time given there is no OS and no dynamic loader?

Upvotes: 2

Views: 1115

Answers (2)

Michael Burr
Michael Burr

Reputation: 340208

You need some way for the device to determine when it is reset which of two possible locations it should start executing from. But generally a bare-metal device has only a single starting location it runs from when it's reset (some controllers can select from two or maybe more entry points based on the logic level of some pins on the device).

We had a similar requirement, and worked out the following scheme:

  • a small bootloader program is required - it's built and linked to be the program that gains control of the CPU at reset
  • the main program image is actually built twice - once for each possible location. Note: the two possible loading locations are fixed and known by the bootloader.
  • there's a small data structure at the start of the program image that contains several bits of information important to the bootloader. Among them are the entry point address of the program and a checksum of the program image

The bootloader examines the fixed, well-known locations to checksum the two possible images.

  • if it finds no valid images, it simply loops (the watchdog will reset the device, but that doesn't really matter - it's a brick until a valid main program is loaded)
  • if it finds only one valid image, that's the entry point that it jumps to.
  • if it finds both images are valid it uses other information in the data structure to determine which one to give control to (version information, last known good, whatever your policy might be).

The key to this is that the bootloader must be simple and stupid. It's not easily upgradeable, so you want it to be stupid enough that it can't have bugs.

Now the device can be upgraded while it's running by flashing the image to the non-running location (the Cortex-M3 device we have allows this - if the LPC1758 doesn't allow this, then you have to have something that runs from RAM perform the flash update). Reset, and the bootloader picks up the newly flashed image.

The system requires a little up-front work to get the bootloader running and rock-solid, but once it's working updates are 100% reliable (if the new flash doesn't complete, the old image is the only one that checksums, so it'll run at next reset - no bricks). The main disadvantage - and it's a big one - is that you essentially lose half your flash address space for the main program since the flash has to be able to hold two compete images.

Upvotes: 0

Dan
Dan

Reputation: 10393

For bare-metal embedded systems like yours, this is accomplished by compiling/linking your code as relocatable code, also known as Position Independent Code.

How this is accomplished is influenced by the processor, and the actual approach is implemented by your development toolset, so you'll want to consult with the documentation for your cross-development tools. It is usually a set of compiler & linker options (incl. your linker command script, if you have one) that determine how things are laid out & what registers are used to access them.

Things become a little easier when you're working with a platform (processor & OS) that supports an MMU (not on the CM3, sorry) - then the code can be located anywhere in physical memory, but via the MMU, its logical address space can be different. Thus, at link time, addresses for code & data can be fixed, and then at load time, the logical address space is set up via the MMU, and the program is none the wiser.

You might find this other SO question ("Trying to load position independent code on cortex-m3") helpful as well.

Upvotes: 2

Related Questions