Joe
Your initial boot loader always occupies the first sector of Flash (due to its reset vector). It also defines the security (which will be left unprotected initially).
To change the security you need to erase (at least) the first sector and reprogram (at least) the reset vectors plus the new security setting.
There is no advantage of avoiding the first sector with the rest of the boot loader code since it has to update at least 'a part' of itself anyway and if there is a reset/power cycle at that point the board will no longer be operational (without reloading with debugger).
I have added the method that I have used in several products where the boot loader has needed to be exchanged in the field (and which can be used to lock the device if the new boot loader code sets the appropriate flash configuration value). It uses the uTasker Flash programming interface (which can be replaced by whatever ones you are using) and integrates the new boot loader code by including it as an array in a header file called serialArray.h (to create such an array the utility uTaskerFileCreate can be used: uTasker Utilities ).
This code is put into an application (your normal application can always include the latest boot loader version and update whenever necessary) that is loaded using your original loader. It can be called to check that the boot loader is up-to-date (when it does nothing) or to update a new version whenever needed. If you look carefully the flash configuration is programmed as priority as soon as the first sector has been erased.
Regards
Mark
P.S. Note also that you can immediately set the security in the first boot loader since it doesn't restrict the reprogramming of future applications and boot loaders anyway.
P.P.S. The fnUpdateSerialLoader() can also be added to an application at any time since it doesn't need to be foreseen at the outset.
Kinetis for professionals: http://http://www.utasker.com/kinetis.html
#include "serialArray.h"
static void fnUpdateSerialLoader(void)
{
if (memcmp(serial_loader, fnGetFlashAdd((unsigned char *)0x00000000), sizeof(serial_loader)) != 0) {
unsigned char *ptrFlashDestination;
unsigned char *ptrSerialLoader = serial_loader;
if (memcmp(serial_loader, fnGetFlashAdd((unsigned char *)0x00000000), _FLASH_GRANULARITY) != 0) {
_fnEraseFlashSector((unsigned char *)0, _FLASH_GRANULARITY);
_fnWriteBytesFlash((unsigned char *)0x400, &serial_loader[0x400], 16);
_fnWriteBytesFlash((unsigned char *)0, &serial_loader[0], 0x400);
_fnWriteBytesFlash((unsigned char *)0x410, &serial_loader[0x410], (_FLASH_GRANULARITY - 0x410));
}
ptrFlashDestination = (unsigned char *)_FLASH_GRANULARITY;
ptrSerialLoader += _FLASH_GRANULARITY;
while (ptrFlashDestination < (unsigned char *)(32 * 1024)) {
_fnEraseFlashSector(ptrFlashDestination, _FLASH_GRANULARITY);
_fnWriteBytesFlash(ptrFlashDestination, ptrSerialLoader, _FLASH_GRANULARITY);
ptrSerialLoader += _FLASH_GRANULARITY;
ptrFlashDestination += _FLASH_GRANULARITY;
}
}
}