EmbeddedRelated.com
Forums

Bootloader Placement

Started by Tom Lucas April 19, 2006
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. 


In comp.arch.embedded,
Tom Lucas <news@REMOVEautoTOflameREPLY.clara.co.uk> wrote:
> > 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. >
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)
"Tom Lucas" <news@REMOVEautoTOflameREPLY.clara.co.uk> wrote in message
news:1145440222.4772.0@damia.uk.clara.net...
> 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.
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.
> 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.
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.
> 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 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.
> 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.
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.
> There must be a better way of doing this but I'm not sure which direction
to
> proceed.
Peter
On Wed, 19 Apr 2006 10:50:31 +0100, "Tom Lucas"
<news@REMOVEautoTOflameREPLY.clara.co.uk> wrote:

>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. >
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
Tom Lucas <news@removeautotoflamereply.clara.co.uk> wrote:

> 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.
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.
"Stef" <stef33d@yahooI-N-V-A-L-I-D.com.invalid> wrote in message 
news:837a6$4446153d$54f63171$11813@publishnet.news-service.com...
> In comp.arch.embedded, > Tom Lucas <news@REMOVEautoTOflameREPLY.clara.co.uk> wrote: >> >> 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. >> > 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.
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?
> 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) >
"Hans-Bernhard Broeker" <broeker@physik.rwth-aachen.de> wrote in message 
news:4ammlpFtmsapU2@news.dfncis.de...
> Tom Lucas <news@removeautotoflamereply.clara.co.uk> wrote: > >> 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. > > 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. >
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.
Tom Lucas wrote:

> 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. > >
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/
"Tim Wescott" <tim@seemywebsite.com> wrote in message 
news:rv-dnZDKDcS61tvZnZ2dnUVZ_sOdnZ2d@web-ster.com...
> Tom Lucas wrote: > >> 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. > 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. >
I spent a bit of time getting everything reduced in size but all the boot loader code now fits in a sector comfortably (rather too comfortably now - I needn't have spent so much time pruning bits off the GUI). As for protecting the first sector, I've been in two minds. The sectors are addressed in a for loop with explicit boundaries so there is no way that software can address the first sector. Nowhere else in software can write to flash and the functions will be out of scope to them anyway. In the event of an open track on address line 16 then it's possible for the first sector to be addressed but in that case the whole system would be knackered anyway. I suppose locking the sector gives some peace of mind but it might be overkill and cause trouble in the field if I ever want to update the boot loader. Anyway, using the methods you and the other chaps in this thread have suggested it all seems to be working :-D Many thanks to all.