Bootloader Placement

I have written a bootloader to reside in my first sector (128Kbyte) of flash which, firstly copies all code and data from flash to RAM and then checks data on an MMC card to see whether an update of the flash is necessary and, if so, copies new program data into the flash. At the moment I have two projects - the bootloader as a stand-alone loader and the full application, which has the bootloader code as part of it.

What I'd like to do is seperate the bootloader code from the application code and have the boot loader pass control to the application once it has done its checks and, if necessary, reprogramming. However, I don't think I could have the application as stand-alone code as well because it would then be re-initialising the hardware and memory of what was initialised previously in the bootloader.

My thoughts were to define the first flash sector as a seperate linker section and locate all the bootloader functions and data in there but as part of the application software. Then, when a reprogram takes place I just don't write to the first sector. The problem with that is that the old bootloader then does not know where to jump to in the application and also the copy from flash to RAM on startup won't know how much there is to copy. I only want to write to the bootloader area when the loader itself is to be updated because, if it fails, JTAG is the only recovery and that won't be available in the field.

There must be a better way of doing this but I'm not sure which direction to proceed.

Reply to
Tom Lucas
Loading thread data ...

And is re-initializing a problem? I have a simular setup here and let the application just initialize the hardware all over again. But if that is not possible, you can maybe first check the registers in your application and only re-program when required. Later on you may also find that your application requires different hardware setup than your original boot loader performs so re-programming is even required.

Only problem I have found using this approach was some clock and remap registers on atmel ARM chips. I just check them (or their effects) and change if required. The remap on the Atmel AT91RM9200 for instance is a toggle, so you only want to set it once. It can't be checked directly, but you can find the state by checking for RW memory at address 0.

--
Stef    (remove caps, dashes and .invalid from e-mail address to reply by mail)
Reply to
Stef

flash

and,

application,

I use a bootloader/diagnostics and a seperate application code. In my case the main code executes directly from Flash but the bootloader finds the image, checks the CRC and jumps to the beginning. The startup code, crt0.s, for the app branches is always at the beginning of the app image. In my case, if the CRC fails the bootstrap reports that and waits for software update via serial.

then

I init the hardware in the bootloader but most of it is in a passive state. When jumping into the app all hardware is passive - no interrupts or DMA. In the app I re-init the hardware, interrupt vectors etc.

just

The problem is what happens to any functions or data that is shared by the bootloader and main code. You'll need two copies with different names - think memcpy, strcmp, sprintf - otherwise when you update one piece you had better check that nothing has moved in the other that might get used.

copy.

be

Although I can update the bootloader from serial it is not done in the field for the same reason you state - the only way out of an error is JTAG reprog.

to

Peter

Reply to
Peter Dickerson

IN my opinion - keep the areas completely separate and overlay them at the latest stage possible, but if you need to reinitialise peripherals etc, you could write a signature into RAM after the bootloader finishes, and force a hardware reset. Once the boot code sees the signature - and no 'boot' signal, pass control straight to the application without initialising hardware.

-Andrew M

Reply to
Andrew M

As has been said, re-initialization shouldn't usually be problematic

--- at worst, it'll just be a small waste of time on startup. If in your case the hardware really can't be initialized more than once, I think you should consider splitting up your mental image of the job into *three* parts: a bootloader, a flash-updater, and the main application. The bootloader would treat both of the others as optional. I.e. if they're present, they're executed. This requires some management (how to test whether the code is present, how to avoid memory space collisions between flasher and main app...). This would allow to keep all initializations that can't be re-done in the bootloader.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

The only common peripheral between the boot loader and application is the LCD which would have to be initialised again in the application to ensure that the GUI knew where everything was. However, I guess it would either reject any changes whilst running or just end up set up to how it was. Come to think of it, I only need to initialise the screen in the boot loader if a reprogram is required and I can then inisist on a restart before running the application.

However, the crt0.s in both projects will initialised the SDRam and the caches but I could modify the application not to do that. Perhaps it doesn't matter if it gets set up twice?

If I redefined the application's flash to start at sector 1 then it should just assume that it's a solo program entered from reset although it was jumped to from the boot loader. If the last command of the boot loader is a branch to sector 1 then that should work? Right?

Reply to
Tom Lucas

It's an interesting thought but the bulk of the boot loader is an MMC card reader and accompanying filesystem so it's probably easier just to lump them together as the flash loading part is so much smaller. I think I could avoid the collisions by altering the flash description for the linker but it is sharing data between that will be tricky. I would need to determine which version of application software is currently loaded and the details of that would only be known to the flash software.

My thought was to pick something that would always be at a known location once compiled and linked and store a unique ID there. I'm not expecting any Prefetch Abort exceptions and don't intend to include a handler so I could use that spot for an ID. On an abort then the ID would be executed and either not be recogized or run and flow onto the Data Abort which would catch it. This would work as long as the ID isn't interpretted as a branch I believe.

Reply to
Tom Lucas

The way I've seen to do this works best in a flash that can be protected sector-by-sector. Put the bootloader into the sector where your processor boots, and protect that sector. If necessary use multiple sectors, but it's a good idea to make bootloaders as small as possible. Set up the boot loader to _always_ branch to the beginning of the lowest unprotected sector once it detects application code, and _always_ load app code there.

To run stand-alone app code just replace the bootloader with a jump, or your minimal hardware setup and a jump.

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Posting from Google?  See http://cfaj.freeshell.org/google/
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.