¿Por qué necesitamos un programa separado en la misma memoria de programa flash de un microcontrolador, específicamente STM32F103, que se llama cargador de arranque?
¿Qué tiene de especial para mantenerlo separado del programa de aplicación principal?
En términos generales, ¿un gestor de arranque de un sistema basado en microprocesador (por ejemplo, PowerPC MPC8270) realiza el mismo trabajo que el de un microcontrolador (por ejemplo, ARM STM32F103) o están haciendo trabajos fundamentalmente diferentes entre sí y, sin embargo, ambos se denominan 'cargador de arranque' ?
microcontroller
stm32
programming
flash
bootloader
alt-rose
fuente
fuente
Respuestas:
Un gestor de arranque en un microcontrolador es responsable de actualizar el firmware principal a través de un canal de comunicación que no sea el encabezado de programación. Esto es útil para actualizar el firmware en el campo a través de BLE, UART, I2C, tarjetas SD, USB, etc. Sería extremadamente inconveniente requerir que los clientes compren programadores solo para actualizar el firmware en sus dispositivos.
La razón por la cual el gestor de arranque se mantiene separado es por la confiabilidad. El cargador de arranque y el código de la aplicación se colocan en secciones separadas de flash, de modo que el cargador de arranque puede borrar y volver a escribir el código de la aplicación sin cambiar nada relacionado con el código del cargador de arranque.
Si el gestor de arranque y la aplicación se mantuvieran juntos, entonces el código del gestor de arranque debería copiarse en la RAM antes de que pudiera ejecutarse, ya que cualquier actualización de firmware borraría el código del gestor de arranque en flash. Si se corta la energía con el código del gestor de arranque en RAM y se borra el flash, el dispositivo quedaría bloqueado.
fuente
main()
función de inicio . Al encenderse, el código de inicio del cargador de arranque se ejecuta y llama al cargador de arranquemain()
. El programa del cargador de arranque busca un programa de aplicación válido y luego salta al código de inicio del programa de aplicación que llama al programa de aplicaciónmain()
. El código de inicio de cada programa inicializa el entorno de tiempo de ejecución C para el programa respectivo (es decir, inicializa variables, pila, etc.) y, por lo general, ninguno de los programasmain()
vuelve al código de inicio.main
.Para que el proceso de carga se pueda recuperar de los errores. Supongamos que hay un error de comunicación o desconexiones de energía durante una actualización. Si el gestor de arranque fuera parte de la aplicación que estaba actualizando, el usuario no podría volver a intentarlo sin usar hardware especial para volver a cargarlo en el gestor de arranque.
Algunos microcontroladores no pueden ejecutar código desde la RAM. Si el gestor de arranque se mezcló con el resto del software, entonces no podría actualizar su software porque no puede borrar las páginas de flash que está ejecutando actualmente. La solución consiste en grabar primero el nuevo código en la segunda mitad del flash y luego saltar a él. El nuevo código luego se copia en la primera mitad del flash. Por supuesto, la desventaja es que el flash de grabación generalmente es lento y ahora que tiene que hacerlo dos veces, el proceso de carga puede demorar hasta el doble. Además, esta solución limita el tamaño de su aplicación para que no sea mayor que la mitad de su flash total.
Los cargadores de arranque bien escritos intentan verificar que existe un código válido en el dispositivo antes de intentar ejecutarlo. Si el gestor de arranque y otro código se mezclaran, ¿cómo podría estar seguro de que su rutina de validación funcionaría si no se cargara todo el código?
Autenticación. Los cargadores de arranque seguros intentan verificar que la aplicación cargada coincida con una firma digital antes de ejecutarla. Pero si el cargador de arranque y otro código se mezclaron, entonces no puede controlar lo que se ejecuta en el dispositivo porque una vez que el usuario carga un nuevo código, no puede controlar lo que sucede al inicio.
fuente
Generalmente están ahí para permitirle actualizar su programa de aplicación principal.
Necesita un código que sepa cómo borrar y reprogramar parte del flash interno, que no puede ser el programa principal, ya que cuando se borra no podría reprogramarse.
fuente
El gestor de arranque permite que la MCU se comunique con otra cosa para aceptar un nuevo programa, almacenarlo y ejecutarlo después de un reinicio. Si no tenía un gestor de arranque, se necesita un programador para acceder a la memoria y poner el programa en su lugar.
fuente
Además de las otras respuestas correctas sobre permitir la reprogramación del firmware principal desde el cargador de arranque, otro beneficio de tener el cargador de arranque separado es que puede separar lógicamente las tareas de "hacer una vez en el arranque" del código que necesita durante el tiempo de ejecución. Luego, una vez que el gestor de arranque finaliza sus tareas de configuración inicial, el firmware principal puede desalojar el gestor de arranque con todo el código que ya no necesita de la memoria, ahorrando un importante espacio de RAM. Es posible lograr esto de otras maneras, pero la división del cargador de arranque / firmware lo hace mucho más fácil en muchas arquitecturas.
fuente
La respuesta corta es porque el software es increíble.
Podría tener todo lo que hace el gestor de arranque como "hardware puro". Pero es mucho, mucho, mucho más fácil tener las tareas que el gestor de arranque se escribe como software y luego se interpretan mediante hardware.
Estas tareas pueden implicar configurar el hardware para que se ejecute el software "real" (por ejemplo, en una Raspberry Pi (a través de @ErikF)), tener un protocolo para reemplazar el programa "real" antes de que se ejecute (marque un pin, si ese pin se establece y luego vuelve a actualizar el programa real), o incluso configura el entorno de software para el programa "real".
En un software con menos microescala, cuando ejecuta un archivo ejecutable, el cargador de aplicaciones mueve cosas como cargar partes de sus datos en la memoria, a veces arregla direcciones, configura argumentos para cosas principales u otras cosas globales, hace girar las bibliotecas proporcionadas por su sistema operativo y luego salta al inicio del
_main
código. Algunas de estas cosas pueden ser realizadas por un gestor de arranque.En un microcontrolador, algunas de las tareas que realiza un gestor de arranque podrían dividirse en el programa. El compilador para su plataforma podría inyectar automáticamente el código de "configuración" en cada ejecutable.
Pero tenerlo en el gestor de arranque significa que el mismo compilador podría funcionar en hardware diferente, ya que el gestor de arranque puede "ocultar" la diferencia entre las plataformas.
Para colmo, el hecho de que un destello del programa principal no arriesga el gestor de arranque (y la capacidad de actualizar el programa principal), y tener un gestor de arranque no trivial es una gran cosa.
fuente
Una respuesta que no se ha cubierto es la necesidad de separar las preocupaciones debido a las limitaciones del lenguaje C.
En general, los gestores de arranque se escriben en una combinación de ensamblaje y C, con la etapa inicial de arranque en ensamblador.
Esto se hace para configurar ciertas cosas como:
Esta es una aproximación muy aproximada de los pasos tomados y estoy describiendo el proceso de arranque ARM, es diferente nuevamente para x86 y otras arquitecturas.
Sin embargo, la razón principal sigue siendo la misma: la asignación de la pila C debe hacerse desde el ensamblaje.
fuente
Una parte de la pregunta que no se ha respondido hasta ahora es la diferencia entre los gestores de arranque en los microcontroladores y los sistemas de microprocesadores.
Microcontrolador
La mayoría de los microcontroladores tienen memoria ROM incorporada que contiene su código de programa. Cambiar este código generalmente requiere un dispositivo programador que se conecte a la interfaz de programación del microcontrolador (por ejemplo, ISP en ATMega). Pero estas interfaces de programación a menudo no son muy convenientes de usar, en comparación con otras interfaces, ya que pueden no estar fácilmente disponibles en el contexto dado. Entonces, por ejemplo, aunque casi todas las computadoras cuentan con puertos USB, la interfaz SPI necesaria para ISP es mucho más rara, y otras interfaces como la interfaz PID utilizada en ATXMega solo son compatibles con hardware de programación dedicado.
Entonces, por ejemplo, si desea actualizar el software desde una computadora normal sin ningún hardware externo, puede usar un gestor de arranque que lea desde un tipo diferente de interfaz (por ejemplo, RS232, USB o RS232 a través de USB como en el Arduino) para programar el dispositivo sobre interfaces comunes.
Dicho esto, si no necesita esta funcionalidad, el gestor de arranque es completamente opcional. El microcontrolador aún puede ejecutar su código completamente sin el gestor de arranque.
Microprocesador
En un microprocesador, las cosas son un poco diferentes. Si bien la mayoría de los microprocesadores cuentan con una ROM que es lo suficientemente grande como para un cargador de arranque, esas ROM no son lo suficientemente grandes como para contener un sistema operativo completo. Por lo tanto, el propósito del gestor de arranque es inicializar el hardware, buscar un sistema operativo de arranque, cargarlo y ejecutarlo. Por lo tanto, el gestor de arranque es crítico para cada arranque.
En los sistemas x86 / x64, este gestor de arranque es el BIOS o el UEFI (básicamente una versión más nueva de un BIOS).
A veces incluso puede tener múltiples cargadores de arranque ejecutándose en una cadena. Por ejemplo, si tiene un sistema de arranque dual con Windows y Linux, puede terminar con lo siguiente:
Entonces, en este caso, había tres piezas de software que pueden considerarse un gestor de arranque. Tanto GRUB como el cargador de arranque de Windows están allí principalmente para brindar al usuario una opción de selección de arranque más conveniente que la que BIOS / UEFI les daría. También permite iniciar múltiples sistemas operativos desde el mismo disco duro o incluso desde la misma partición.
TLDR
Entonces, mientras que en ambos sistemas el gestor de arranque hace cosas similares (ayudando al usuario a elegir qué código arrancar), ambos difieren enormemente en cómo lo logran y qué hacen exactamente.
fuente