¿Qué es el cargador de arranque y el código de inicio en el sistema integrado?

Todos los procesadores tienen alguna forma de arranque específica del procesador. Por lo general, hay alguna dirección en el espacio de direcciones del procesador, por ejemplo, 0xFFFF0000, donde el procesador lee esa memoria. El valor que encuentra utiliza como una dirección para codificar y comienza a ejecutar código en esa dirección.

Lo que harían los diseñadores de chips o placas es asegurarse de que un flash o alguna otra forma de memoria no volátil (ROM) esté asignada a ese espacio de direcciones, de modo que el código de arranque del procesador y esa dirección al código de arranque en ese especial dirección, estará allí para que el procesador la lea cuando se encienda la alimentación y se libere el reinicio (la RAM es volátil, apague la alimentación y perderá los datos, vuelva a encenderla y obtendrá algunos datos aleatorios hasta el momento RAM se escribe con otra cosa).

Entonces, el primer código que ejecuta un procesador a menudo se llama cargador de arranque, y algunos pueden debatir que la segunda mitad del cargador de palabras implica que este código puede “arrancar” el sistema operativo o cualquier aplicación que se ejecute, y también como un segundo La función proporciona una capacidad de “cargador” para los desarrolladores. Si alguna vez ha utilizado U-Boot o incluso GRUB o muchos otros cargadores de arranque, puede entender que si no toca nada, arrancará el valor predeterminado, la aplicación integrada o el sistema operativo, lo que sea.

Pero si interrumpe el proceso de arranque, e interrumpir ese proceso es muy específico para la plataforma y el software, a veces tiene que presionar un botón o dos pines juntos o enviar un escape o algún otro personaje en un puerto serie / UART, etc. ., y luego entra en el modo de cargador donde puede cambiar lo que arranca y / o en lugar de que el cargador de arranque cargue el programa predeterminado desde flash / ROM, podría permitirle, por ejemplo, usar XMODEM o ZMODEM o un puerto Ethernet y protocolo para cargar un programa de prueba en la RAM, luego le permite ejecutar ese programa en lugar del programa predeterminado.

Algunas personas llaman al software de arranque un gestor de arranque, incluso si no le permite interrumpir el proceso y cargar algún programa alternativo, porque ese código de arranque podría estar “cargando” la aplicación en la RAM desde el almacenamiento no volátil de todos modos.

No todos los gestores de arranque necesitan copiar la aplicación desde un almacenamiento no volátil (flash / ROM, disco duro, CD-ROM, etc.) a la RAM. Algunos sistemas y algunas aplicaciones se ejecutan desde la memoria flash / ROM. Una PC, por ejemplo: el verdadero gestor de arranque en una PC es el BIOS, que es un programa que vive y se ejecuta desde flash / ROM. Para sistemas con DRAM como una PC, de todos modos debe abrir el sistema DRAM. Se requiere una gran cantidad de código para configurar el hardware de modo que la DRAM funcione, y a veces puede ver algún estado de esto en el monitor cuando se inicia una PC. Si tiene SRAM en su sistema, entonces también puede requerir algo de inicialización, pero generalmente no es tan complicado como DRAM, y a menudo está listo instantáneamente y listo para usar con poca o ninguna configuración, diferentes procesadores y diferentes sistemas son … diferentes.

Por lo tanto, el procesador no está restablecido, de alguna manera codificado en el hardware del procesador. Ha encontrado el punto de entrada al código de arranque y comenzó a ejecutar ese código. Ese código, en general, necesita poner en funcionamiento los periféricos y la RAM y luego ejecutar la aplicación principal. O al menos se necesita tanto hardware antes de iniciar esa aplicación.

Cargar Linux en un sistema embebido puede ser tan simple como recuperar RAM y copiar el kernel de la ROM a la RAM, tal vez preparando algunos registros y tal vez llenando algunas ubicaciones de memoria que el kernel mira con tal vez el tamaño de la memoria y una línea de comando alternativa por ejemplo, luego bifurca al inicio del núcleo. No tiene que copiar el núcleo en algunos sistemas; puedes simplemente ramificarte a la ROM donde vive. Entonces Linux abrirá el resto del sistema. En una PC, el BIOS hace muchas cosas, como mostrar video, DRAM, enumerar los periféricos del bus PCI (e), mostrar el disco duro u otro sistema de archivos como dispositivos, luego usar el definido por el usuario en el disco duro del BIOS o como periférico (memoria USB o CD-ROM, etc.). El comienzo del sistema de archivos contendrá algún tipo de inicio del sistema operativo basado en las reglas del código del BIOS. Y ese puede ser otro cargador de arranque (GRUB, U-Boot, etc.), que finalmente copia el código de inicio del kernel o del sistema operativo a la RAM y luego se ramifica a él …

Los términos gestor de arranque y código de inicio se pueden usar indistintamente. Algunas personas pueden ser quisquillosas con respecto a que son diferentes o sutiles diferencias, pero generalmente tiene que ver con la complejidad, un cargador de arranque como U-Boot que tiene controladores Ethernet y controladores de sistema de archivos, etc. es, en cierta medida, un sistema operativo en él. auto, de cualquier manera U-Boot es muy complicado.

El código de inicio para un microcontrolador, por ejemplo, puede ser tan simple como unas pocas líneas de código, establecer el puntero de la pila y bifurcarse a main. Y el código de inicio / gestor de arranque puede tener cualquier nivel de complejidad intermedio. Como ya se mencionó, algunos sistemas integrados arrancan y ejecutan sus aplicaciones desde la ROM, por lo que no es necesario copiar y ejecutar. Otros requieren la copia y ejecución para la aplicación principal.

A veces, el hardware o algún otro esquema se involucra. Es posible, por ejemplo, muchas soluciones basadas en FPGA, donde el hardware lee cosas al encender desde una ROM y las copia. Luego, cuando se libera el procesador u otra lógica, su programa u otros datos están mágicamente allí en la RAM, listos para usar. Aunque cuando está apagado, vive en una ROM que normalmente no tocas. TheRaspberry Pi tiene otra solución más. El chip tiene dos procesadores, uno es el ARM y el otro es una GPU, un procesador de gráficos, un conjunto de instrucciones completamente diferente, diseñado para operaciones matemáticas, etc. Hay alguna forma, quemada en el chip (probablemente una ROM en el chip) un pequeño gestor de arranque que es suficiente para abrir y leer la tarjeta SD. Esto es GPU BTW; el BRAZO está en reinicio. Luego, la GPU lee su primer archivo del gestor de arranque de la tarjeta SD, lo copia en la RAM y lo ejecuta.

Ese gestor de arranque hace más cosas, como abrir DRAM, y luego copia el gestor de arranque de la segunda etapa (¿tercera?) Más complicado de la tarjeta SD a DRAM y luego lo ejecuta. Es probable que ese código contenga la aplicación GPU para realizar las funciones de pantalla / visualización para el sistema. También, una vez que el video y todo está listo, lee la tarjeta SD una vez más y copia la aplicación ARM de la tarjeta SD a la DRAM, completa algunos elementos en la RAM (vector de arranque en la tabla de excepciones (una rama al núcleo)) y algunos otros elementos en ubicaciones conocidas que desea el código de arranque del kernel de Linux. Luego libera restablecer en el BRAZO. El ARM en este punto se despierta con su aplicación, el núcleo, mágicamente en la RAM …

El cargador de arranque es el código de inicio ejecutado por el sistema integrado, donde los módulos de interfaz como RAM, controlador Flash, controlador de interrupción, interfaz serial y controladores de bus USB / I2C, etc., se encienden e inicializan. También puede contener pequeños casos de diagnóstico para verificar la funcionalidad de los componentes. Después de realizar su trabajo, carga el núcleo en la RAM e invoca el código de inicio del núcleo. Recientemente, la mayoría de los procesadores integrados son compatibles con 2 cargadores de arranque, el cargador de arranque de primer nivel se almacena en la ROM (la plataforma TI Davinci llama como UBL), donde inicializa la interfaz UART y el módulo flash para cargar el cargador de arranque de segundo nivel como U-boot para que este gestor de arranque sea fácil de implementar y depurar. 3 niveles es la carga del kernel. Más detalles, consulte la documentación de U-boot o Boot Loader en las plataformas de Texas Instruments www. ti .com / lit / an / spraai4a / spraai4a.pdf. Puede obtener una comprensión detallada de las funcionalidades de cada cargador de arranque de nivel.

En un sistema integrado que no tiene SO, el código de inicio es el código que se ejecuta antes de que se llame a la función main (), en general, las tareas que realiza el código de inicio son:

  1. Configuración del contador de programa (PC), puntero de pila (SP),
  2. Asignación de las tablas de vectores intterupt a la dirección de las Rutinas de servicio de interrupción (ISR),
  3. Borra la memoria interna de datos en algunos casos,
  4. Establecer la frecuencia de reloj predeterminada del sistema,
  5. Finalmente bifurcando la ejecución al main (),

y hay que tener en cuenta que cada vez que se restablece la placa, el código de inicio no se ejecutará, solo la PC se establecerá en main (), el código de inicio solo se ejecuta en el encendido.

El cargador de arranque es el código que carga el sistema operativo.

El gestor de arranque es, en términos generales, un código que se ejecuta en el instante en que la CPU sale del reinicio, hasta que pasa el control del sistema al sistema operativo. Su propósito es realizar la inicialización básica de la CPU y, a veces, algunos otros dispositivos periféricos, como subsistemas de disco, a veces controladores de red, quizás temporizadores, controlador DMA, controlador de video, UART (s), etc. A veces puede tener un componente interactivo , o puede ser completamente invisible.

Hay un par de cargadores de arranque comunes que se usan ampliamente en sistemas embebidos. syslinux y uboot son algo comunes, pero hay otros. Algunos sistemas integrados que funcionan sin un sistema operativo (bastante común) realizan la inicialización como parte de la aplicación. Es posible, aunque no estoy seguro de qué tan práctico es escribir su propio gestor de arranque para algunos sistemas operativos. En los sistemas de PC, el inicio del sistema lo realiza inicialmente el BIOS, y luego se carga un cargador de arranque desde el disco (sin embargo, desea definirlo) o mediante una red (PXE). Grub y el gestor de arranque de Windows son los comunes en esa arquitectura; De nuevo, hay otros. No los describiría como sistemas integrados, pero eso es algo subjetivo.

Gracias por A2A!

Boot-loader es una aplicación que le permite borrar la aplicación principal y volver a cargar la nueva versión de esta aplicación. En el caso típico, cambiamos entre el cargador de arranque y la aplicación principal mediante el reinicio de MCU. Por lo tanto, una parte muy pequeña del cargador de arranque podría ejecutarse incluso antes de la función _Startup () y simplemente decidir si se ejecutará el cargador de arranque o la aplicación principal. Después de eso, se ejecutará la función apropiada _Startup () y el código de la aplicación o del cargador de arranque.

El código de inicio es un código corto que borrará su RAM después de reiniciar e inicializar variables (copiar de flash a RAM). También podría inicializar el mapa de memoria (habilitar / deshabilitar EEPROM / Flash, establecer registro, RAM, alineación EEPROM, solo para MCU S12 antiguas, deshabilitar / habilitar watchdog, …). Las tareas para el código de inicio dependen de sus definiciones, pero inicializar RAM es el paso más importante. En el caso de núcleos S12 (X) y CW Classic IDE, el código de inicio predeterminado está en el archivo Start12.c. En el caso de S12Z core y CW Eclipse IDE, el código de inicio predeterminado está en el archivo Start12z.c.

Estos archivos generalmente se ejecutan como la primera aplicación principal anterior. Restablecer vector normalmente apunta a la función _Startup ().

El cargador de arranque es el código utilizado para cargar el sistema operativo o la aplicación que ejecuta el procesador o microcontrolador.

Este es el término genérico, pero el gestor de arranque se puede utilizar para cosas más específicas, como la actualización del firmware o la elección del sistema operativo o el programa de copia en un procesador específico.

mientras que el código de inicio para el controlador es para inicializar tablas de vectores, apilar el contador del programa de puntero, etc.

Hay una delgada línea entre dos. a veces, el código del gestor de arranque y el código de la aplicación principal tendrán su propio código de inicio

Todas las CPU tienen un proceso de arranque. Algunos son tan simples como “ir a esta dirección y comenzar a correr” o “saltar a la dirección almacenada en esta ubicación y comenzar a correr”. Las CPU más complejas pueden requerir muchas cosas, como una carga en serie de configuraciones o una inicialización de hardware dentro de los primeros 100 ciclos. Al menos, todos ellos son mejores que tener que alternar el código a través de interruptores y espero que no los hayas estropeado.

En general, el código que se ejecuta desde uno de esos saltos, cargas en serie o conmutadores de palanca es el gestor de arranque en un sistema integrado. Comenzará y configurará las partes del sistema que se necesitarán. Esto puede incluir memoria, almacenamiento, redes e interrupciones. El gestor de arranque hace lo suficiente para que el código de los desarrolladores se inicie en un entorno impecable.

Para sistemas integrados, la línea puede difuminarse. El gestor de arranque puede ser algo que pone en funcionamiento un sistema operativo completo. Puede ser un código de inicialización que inicia un intérprete que ejecuta comandos de usuario / desarrollador. Puede ser el código real que se desarrolló para el producto. De cualquier forma que lo corte, si es lo primero que ejecuta y configura el hardware, probablemente pueda llamarlo el gestor de arranque.

Un gestor de arranque en el contexto de un sistema integrado prepara el sistema para cargar el sistema operativo desde el dispositivo de arranque. El gestor de arranque generalmente se divide en dos partes.

  1. Proveedor proporcionado: el proveedor proporciona este código (como TI, Qualcomm, etc.). Este código generalmente se actualiza en la ROM del procesador y se ejecuta cuando el dispositivo se ENCIENDE (similar al BIOS). Este código es independiente del sistema operativo que luego se cargará en el sistema. El objetivo de este gestor de arranque es encontrar y cargar el gestor de arranque primario. El código fuente no será compartido por el proveedor y no puede modificarse.
  2. Cargador de arranque primario: este código generalmente depende del sistema operativo. El objetivo de esto es buscar el sistema operativo y preparar el sistema para cargar el sistema operativo. Ejemplo inicializar la memoria DDR. El usuario puede modificar este código y agregar funciones adicionales si es necesario.

Cuando nace un bebé humano, comienza a llorar. Nadie enseña. Sabe llorar. El algoritmo para llorar se almacena en el código de arranque de la mente humana.

Del mismo modo, el sistema conoce pocas cosas por defecto y estas cosas se almacenan en el código de arranque. Posteriormente se puede agregar firmware adicional que se llama firmware del sistema. En nuestro caso, cómo fingir llorar.