I'm confused about how to allocate boot loader memory space in the pic18 micro controller and spend sometime researching on it and landed up here .
I'll put my question :
I have a controller whose linker script looks like this and it defines the memory sections of the controller (which includes the SFR,GPR and other memory starting and ending locations).
My question is how does the boot loader should be placed in micro controllers, should they be kept on the starting of program memory?
I'm having this doubt because one one example this guy advocates keeping the boot loader on program memory locations 0x000-0xfff
Should all bootloaders replace the starting address of programming memory if we want to use boot loaders?
Is there any thing we need to be careful while allocating space for bootloaders?
/
Original linker fileof pic18
/ File: 18f47j53_g.lkr
// Generic linker script for the PIC18F47J53 processor
#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN
LIBPATH .
#IFDEF _CRUNTIME
#IFDEF _EXTENDEDMODE
FILES c018i_e.o
FILES clib_e.lib
FILES p18f47j53_e.lib
#ELSE
FILES c018i.o
FILES clib.lib
FILES p18f47j53.lib
#FI
#FI
#IFDEF _DEBUGCODESTART
CODEPAGE NAME=page START=0x0 END=_CODEEND
CODEPAGE NAME=debug START=_DEBUGCODESTART END=_CEND PROTECTED
#ELSE
CODEPAGE NAME=page START=0x0 END=0x1FFF7
#FI
CODEPAGE NAME=config START=0x1FFF8 END=0x1FFFF PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
#IFDEF _EXTENDEDMODE
DATABANK NAME=gpre START=0x0 END=0x5F
#ELSE
ACCESSBANK NAME=accessram START=0x0 END=0x5F
#FI
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
DATABANK NAME=gpr5 START=0x500 END=0x5FF
DATABANK NAME=gpr6 START=0x600 END=0x6FF
DATABANK NAME=gpr7 START=0x700 END=0x7FF
DATABANK NAME=gpr8 START=0x800 END=0x8FF
DATABANK NAME=gpr9 START=0x900 END=0x9FF
DATABANK NAME=gpr10 START=0xA00 END=0xAFF
DATABANK NAME=gpr11 START=0xB00 END=0xBFF
#IFDEF _DEBUGDATASTART
DATABANK NAME=gpr12 START=0xC00 END=_DATAEND
DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED
#ELSE //no debug
DATABANK NAME=gpr12 START=0xC00 END=0xCFF
#FI
DATABANK NAME=gpr13 START=0xD00 END=0xDFF
DATABANK NAME=gpr14 START=0xE00 END=0xEAF
DATABANK NAME=sfr14 START=0xEB0 END=0xEFF PROTECTED
DATABANK NAME=sfr15 START=0xF00 END=0xF5F PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
#IFDEF _CRUNTIME
SECTION NAME=CONFIG ROM=config
#IFDEF _DEBUGDATASTART
STACK SIZE=0x100 RAM=gpr11
#ELSE
STACK SIZE=0x100 RAM=gpr12
#FI
#FI
Best Answer
I have always put my PIC 18 bootloaders at the end of program memory. The reason you can't put them at the beginning is that this is where the interrupt vectors also are. Assuming your app uses interrupts, since most do, you don't want the bootloader owning that section of memory.
Build the bootloader as a separate project that has a known fixed starting address near the end of memory. I use a include file to define the things that both the main app and the bootloader need to agree on, like the start address of the bootloader and where the bootloader needs to jump to run the main app. These need to be fixed addresses since different versions of the bootloader and main app need to be able to work together.
Execution does have to go to the bootloader on reset. That means a GOTO instruction at location 0 to the bootloader's known fixed starting address. Since location 0 is in the main app image, this is something the main app code has to provide.
With this kind of project, the main app usually contains a uploader. During its normal operation, it communicates with whatever can provide a new app image. This new app image is stored to a external EEPROM or roughly the second half of program memory. All the complicated code for doing the communication with the host and getting the new app image is contained in the main app.
The bootloader is then a small piece of code at the end of memory that runs from reset. It compares the main app and uploaded image versions and runs checksums on them. Under the right conditions it copies the new app image into the main app area and then runs it. Of course it never runs a main app that has a bad checksum.
There is one small vulnerability with this. To update the main app image, the bootloader has to erase and then overwrite the first erase block of program memory. Unfortunately, that is where the reset vector is. If a power failure or glitch occurs in the few milliseconds when the GOTO at the reset vector isn't there, then the PIC is toast and can only be recovered with a external programmer. Fortunately, that is a very small window of vulnerability, with the odds of it actually happening very very small. Note that a glitch during erasing/writing any of the other erase pages is recoverable. As long as the GOTO at the reset vector is there, the bootloader will be re-run, the main app checksum will fail, and it will attempt to re-write the main app from the stored app image.