Я делал так:
Отдельно заливал бутлодер, настраивал контроллер так, чтобы он всегда с него грузился. Дальше возможно два варианта - либо по состоянию какой нибудь ноги контроллера определять, хочет ли пользователь, чтобы работал загрузчик, или же выходить в основную программу. Другой вариант - ожидание внешней команды (например, мой загрузчик работал по USART, и в течении 100 мс ждал команды, а затем уходил в основную программу, если команду не получил). В данных вариантах даже если загрузчик не сможет полностью обновить прошивку из за сбоев, всегда будет работать первым бутлодер (если конечно он сам не повредиться, за этим лучше следить либо в нём самом, либо защитить его лок-битами)