• AVR Freaks

Helpful ReplyHot!Update a bootloader from application (bootloader the bootloader itself)

Page: 12 > Showing page 1 of 2
Author
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
2019/03/21 01:51:50 (permalink)
0

Update a bootloader from application (bootloader the bootloader itself)

Hi all,

I've been working with microchip bootloader applications on my PIC32 for several years now. I adapted the original bootloader (from AN1388) to several interfaces (TCPIP, CAN, UART, SPI) with good results. Now I'm trying to extend the functionality of my bootloader with the option to "update the bootloader itself from the application". Therefor I thought of simply including my bootloader library to the application, adapting the ADDRESS_MACROS (so they point to the bootloader area which is 0x9D000000-0x9D00B000) and that's it. Unfortunately it does not work that easily! The controller is stuck after a reboot (not running the bootloader code). Is there some area in the range 0x9D000000-0x9D00B000 I'm not allowed to erase with the page flash erase comand?
Here are my address macros from the main application:

#define APP_FLASH_BASE_ADDRESS (0x9D000000)
#define PROGRAM_FLASH_END_ADRESS (0x9D000000+BOOTLOADER_SIZE-1)
#define APP_FLASH_END_ADDRESS PROGRAM_FLASH_END_ADRESS
#define USER_APP_RESET_ADDRESS (APP_FLASH_BASE_ADDRESS + 0x1000 + 0x970)

Some more information:
* I don't need to rewrite the config settings.
* My bootloader is placed in area 0x9D000000-0x9D00B000.
* XC32 1.41 compiler.
* See attached linker files.

Any help would be appreciated!

Best regards,
Oliver
#1
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 01:57:47 (permalink)
4 (1)
carterb23
...
Now I'm trying to extend the functionality of my bootloader with the option to "update the bootloader itself from the application".

Most bootloaders would specifically prevent themselves being overwritten.
What happens when the FLASH writing code itself gets erased?
Sounds like a sure fire way to convert your product into a brick.
 

Nearly there...
#2
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 02:05:26 (permalink)
0
Hi qhb and thanks for your answer (I'm speechless on your response time ;-))!
 
qhb
Most bootloaders would specifically prevent themselves being overwritten.



How is this be done, could it be my issue? About what memory regions are you talking, that could have this protections?!
 
qhb
What happens when the FLASH writing code itself gets erased?
Sounds like a sure fire way to convert your product into a brick.
 



You are totally right. But after years of further development, it is necessary to update outdated bootloaders, to keep them consistent and have important security features. It is nothing I was intentionally planing to do, but it gets more and more important.
 
Cheers,
 Oliver
 
#3
qhb
Superb Member
  • Total Posts : 9998
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 02:13:57 (permalink)
4 (1)
carterb23
qhb
Most bootloaders would specifically prevent themselves being overwritten.

How is this be done, could it be my issue? About what memory regions are you talking, that could have this protections?!

The bootloader is just firmware that is accepting hex data and programmign it into FLASH memory.
Presumably it know where it is located itself. It would be trivial to compare that against the address to be written, and simply ignore writes over its own memory.
If you have the source to the bootloader, then you should be able to look to see if it's checking the addresses being programmed.
 

You are totally right. But after years of further development, it is necessary to update outdated bootloaders, to keep them consistent and have important security features. It is nothing I was intentionally planing to do, but it gets more and more important.

So you have no option to use ICSP or JTAG to reprogram the bootloader?
 

Nearly there...
#4
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 02:18:57 (permalink)
0
Hi!
 
Yes, I have the bootloader code under my control and it is checking for ranges. But these addresses I adapted, since when bootloading from application, I make sure to not override the application itself (since it is currently being executed) but the bootloader area. So in general the overwrite of the mentioned bootloader area (0x9D000000-0x9D00B000) works, but for some corner cases, things seem to get corrupted and the bootloader application is not going to start. Is there some area I need to prevent during update?
 
Cheers,
 Oliver
#5
crosland
Super Member
  • Total Posts : 1582
  • Reward points : 0
  • Joined: 2005/05/10 10:55:05
  • Location: Bucks, UK
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 02:44:24 (permalink)
5 (2)
What I do is create an app that is the new bootloader, modified to write to the old bootloader memory region(s).
 
Load that using the old bootloader just like any app.
 
Next time you power on the new bootloader is running as the app and you can connect to it fom your client and download the unmodified new bootloader.
 
Reboot and use the newly installed bootloader to reinstall the real app.
 
I try to avoid doing this :)
#6
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 03:42:37 (permalink)
0
Hi crosland!
 
crosland
What I do is create an app that is the new bootloader, modified to write to the old bootloader memory region(s).
 
Load that using the old bootloader just like any app.
 
Next time you power on the new bootloader ...

 
This is exactly what I'm doing (I just add the bootloader as a library to my main application). I'm wondering what I need to erase before programming the new bootloader. Currently I simply erase flash region (0x9D000000-0x9D00B000), the area where the bootloader code will be placed. Is there anything more, maybe "Internal Boot Flash" or anything else?
 
Cheers,
 Oliver
post edited by Oliver - 2019/03/21 05:07:50
#7
Jim Nickerson
User 452
  • Total Posts : 6016
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 06:04:58 (permalink)
5 (1)
I do as Crosland says.
I include the "new modified bootloader" as a const array in the updater app.
The updater app erases the bootloader area and flashes it from the const array.
I used the elfViewer plugin when debugging the app to ensure I knew what memory was used by the app that I had control over.
#8
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 06:07:23 (permalink)
0
Hi!
JANickerson
The updater app erases the bootloader area and flashes it from the const array.



What exactly do you erase. Only the program flash part or also some boot flash?
 
Cheers,
 Oliver
#9
Jim Nickerson
User 452
  • Total Posts : 6016
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 06:19:57 (permalink)
5 (2)
I only erase the flash the bootloader will reside in.
I found if I try to erase and reprogram the config bits  ( the segment that they reside in ) my pic halts on a config mismatch exception ). 
#10
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 06:23:35 (permalink)
0
JANickerson
I only erase the flash the bootloader will reside in.
I found if I try to erase and reprogram the config bits  ( the segment that they reside in ) my pic halts on a config mismatch exception ).



Okay, and I think you also only write the flash the bootloader will reside in? Do you explicitly restrict the flash-write to these region?
 
Cheers,
 Oliver
#11
aschen0866
Super Member
  • Total Posts : 4459
  • Reward points : 0
  • Joined: 2006/01/08 22:18:32
  • Location: San Diego
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 07:20:25 (permalink)
5 (2)
carterb23
... So in general the overwrite of the mentioned bootloader area (0x9D000000-0x9D00B000) works, but for some corner cases, things seem to get corrupted and the bootloader application is not going to start. Is there some area I need to prevent during update?
 
Cheers,
 Oliver


You need to realize that updating 0x9D000000-0x9D00B000 is not good enough. The C runtime startup code, for your bootloader, is located in the BFM (0xBFC00000 - 0xBFC00490) as specified in your bootloader linker script. The startup code must be updated as it needs to go hand in hand with the "bootloader app". 
 
Unless you are using PIC32MZ, which supports dual Flash panel operation, updating the bootloader is dangerous because if the process fails, your device will be bricked.
 
[Added] Your bootloader's vector table is also in the BFM.
post edited by aschen0866 - 2019/03/21 07:23:24
#12
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 07:25:13 (permalink)
0
Hi!
aschen0866
You need to realize that updating 0x9D000000-0x9D00B000 is not good enough. The C runtime startup code, for your bootloader, is located in the BFM (0xBFC00000 - 0xBFC00490) as specified in your bootloader linker script. The startup code must be updated as it needs to go hand in hand with the "bootloader app". 
Unless you are using PIC32MZ, which supports dual Flash panel operation, updating the bootloader is dangerous because if the process fails, your device will be bricked.

How can do so. I tried with NVMemErasePage but it failed (0x490 is not a page at all). A page erase can not be used I think. And what code to put there. Is it always included in the .hex file so my bootloader will write it either-way (if not prevent to do so)?
 
Cheers,
 Oliver
#13
Jim Nickerson
User 452
  • Total Posts : 6016
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 07:27:33 (permalink)
5 (2)
I agree with aschen,
Please do make use of elfviewer when loading the bootloader to ensure you know where everything is, and the app to ensure they will not inadvertently make use of the same 4k page ( maybe for exception handlers... )
Once the bootloader area is erased up till it is flashed by the updater app bricking is quite possible.
As crosland says, I try to do this only when the target board is in hand else the bricking will cause a site visit which in my case is more expensive than my device.
#14
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 08:34:17 (permalink)
0
Hi,
 
okay, I will analyze with elfviewer. But even if the boot flash needs to be updated. How can this be done?
 
Cheers,
 Oliver
#15
aschen0866
Super Member
  • Total Posts : 4459
  • Reward points : 0
  • Joined: 2006/01/08 22:18:32
  • Location: San Diego
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/21 11:35:25 (permalink) ☄ Helpfulby Oliver 2019/03/26 08:50:27
5 (2)
carterb23
 
... Is it always included in the .hex file so my bootloader will write it either-way (if not prevent to do so)?
 

The C runtime startup code, vector table and configuration words should all be in the hex file generated by the XC32 toolchain along with your "bootloader app". Assuming the BFM is not write protected, you should be able to perform Flash page erase and row write the same way you programming the PFM region. However, you can't erase and reprogram the Flash page where configuration words are located. This means you need to exclude any Flash operation within the [1FC0_2000 - 1FC0_2FFF] range. The "valid" area, in your example, would be [1FC0_0000 - 1FC0_1FFF] and [1D00_0000 - 1D00_AFFF].
#16
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/26 08:49:21 (permalink)
0
Hi aschen,
 
should I address over kseg0 (from 0x9FC00000) like for the rest of my bootloader? Or can the BFM not be addressed in that way?
 
Cheers,
 Oliver
#17
aschen0866
Super Member
  • Total Posts : 4459
  • Reward points : 0
  • Joined: 2006/01/08 22:18:32
  • Location: San Diego
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/26 10:10:23 (permalink)
5 (1)
I don't know how you police the address range in your code, but Flash programming uses physical address, so does the hex file format. If you include <sys/kmem.h>, you can access address conversion macros in your code. If you use Flash functions provided by Microchip, it is likely the conversion is already in place, i.e., either KSEG0 or KSEG1 address will get translated to the corresponding physical address.
 
I still think you should avoid updating your bootloader from the application, or at least hide this feature from your average customer. 
#18
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/26 11:09:56 (permalink)
0
aschen0866
I don't know how you police the address range in your code, but Flash programming uses physical address, so does the hex file format. If you include <sys/kmem.h>, you can access address conversion macros in your code. If you use Flash functions provided by Microchip, it is likely the conversion is already in place, i.e., either KSEG0 or KSEG1 address will get translated to the corresponding physical address.

I use microchips NVMem functions and will try with kseg0 addresses, thanks!
 
aschen0866 
I still think you should avoid updating your bootloader from the application, or at least hide this feature from your average customer. 

Of course, this is a developer's function. And even then, we will (hopefully) only use it once to fix a major security bug in devices which are really a long way off and quite hard to disassembly into the bargain! Nevertheless, it has to work, otherwise we have to go there eitherwaywink...
 
I'll come back with news on this!
 
Regards,
 Oliver
#19
Oliver
Starting Member
  • Total Posts : 39
  • Reward points : 0
  • Joined: 2010/10/14 07:42:12
  • Location: 0
  • Status: offline
Re: Update a bootloader from application (bootloader the bootloader itself) 2019/03/26 11:47:59 (permalink)
0
One more question. See below section from my bootloader linker script. I placed kseg0_boot_mem at 0x9FC00490 (can't remember why). Is the erase of before mentioned area still correct or do I have to adapt? And also the config settings starting from 0xBFC02FF0, I can not erase whole page without corrupting them, can I?
 
MEMORY
{
  kseg0_program_mem (rx) : ORIGIN = 0x9D000000, LENGTH = 0xB000 /* Adapt this value to the bootloader app size*/
  eeprom_data (rw) : ORIGIN = (0x9D07FFFF-0x4000), LENGTH = 0x4000
  kseg0_boot_mem : ORIGIN = 0x9FC00490, LENGTH = 0
  exception_mem : ORIGIN = 0x9FC01000, LENGTH = 0x1000
  kseg1_boot_mem : ORIGIN = 0xBFC00000, LENGTH = 0x490
  debug_exec_mem : ORIGIN = 0xBFC02000, LENGTH = 0xFF0
  config3 : ORIGIN = 0xBFC02FF0, LENGTH = 0x4
  config2 : ORIGIN = 0xBFC02FF4, LENGTH = 0x4
  config1 : ORIGIN = 0xBFC02FF8, LENGTH = 0x4
  config0 : ORIGIN = 0xBFC02FFC, LENGTH = 0x4
  kseg1_data_mem (w!x) : ORIGIN = 0xA0000000, LENGTH = 0x10000
  sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000
  configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10
}

post edited by Oliver - 2019/03/26 11:57:19
#20
Page: 12 > Showing page 1 of 2
Jump to:
© 2019 APG vNext Commercial Version 4.5