¿Bootloader en C/C++?
operating-system (4)
¿Es posible crear un gestor de arranque en C o C ++ sin usar algún tipo de ensamblador (y preferiblemente sin usar __asm)? Estoy escribiendo un sistema operativo y me gustaría que estuviera completamente escrito en C y C ++.
Asumiendo el modo protegido x86:
Creo que la respuesta es No, porque necesitas hacer algo como esto para cambiar al modo protegido:
lgdt[GDTR]
jmp CODESEL:FLUSH
FLUSH:
...
No creo que haya una manera de hacer la instrucción jmp
en C / C ++ puro, aunque podría estar equivocado. (No soy un experto aquí; solo estoy haciendo referencia a un cargador de arranque que hice hace un tiempo).
Eso es bastante dependiente del sistema. En la mayoría de los casos, la respuesta será no: tendrá que escribir un ensamblaje personalizado para configurar el tiempo de ejecución de C antes de comenzar a ejecutar su código C. Sin embargo, hay algunas excepciones. El ARM Cortex-M0 , por ejemplo, puede ejecutar el código C directamente fuera de reinicio.
Sin embargo, es de suponer que no está utilizando un M0, por lo que tendrá que escribir algún ensamblaje. Una vez más, depende del sistema / chip, pero es posible que pueda salirse con la suya con algo tan simple como:
reset_vector:
mov sp, SOME_KNOWN_GOOD_STACK_ADDRESS
call c_entry_point
que simplemente inicializa el puntero de la pila y llama al punto de entrada de su programa C. Por supuesto, esta configuración simple depende de que su chip tenga un vector de reinicio / tabla de vectores que lo admita, la RAM (o algo así como RAM) se inicialice antes de que se llame al vector de reinicio, y así sucesivamente. Tienden a haber muchos "errores" en la inicialización temprana del sistema.
Prepárese para ser bastante amigable con la documentación de su compilador, ensamblador y vinculador: generar un binario plano que pueda descargarse rápidamente como un gestor de arranque de primera etapa suele ser un gran problema en sí mismo.
¡Buena suerte!
No, no es posible con C "pura", al menos en x86 ... Además del hecho de que una máquina x86 arrancará en modo real de 16 bits (lo que requiere que un compilador genere 16 bits y no 32 bits). código), necesitará la capacidad de enmascarar interrupciones, configurar registros de segmentos, cargar código en la memoria desde un dispositivo de hardware (es decir, un disco), configurar una pila, acceder a puertos de E / S, etc., todo lo cual en el x86 y otras plataformas requieren acceso a los registros de la CPU y / o comandos de ensamblaje específicos.
En segundo lugar, para C ++, si decide definir alguna clase, necesitará tener algún tipo de configuración manual y ejecutar "constructores" para configurar la memoria de modo que sus clases iniciales puedan existir en algún lugar de la memoria ... también ganó No se puede lanzar ninguna excepción. Esencialmente, cualquier función específica de C ++ que intente utilizar será inútil, ya que estas abstracciones de datos de alto nivel requieren el soporte adecuado del propio tiempo de ejecución del sistema operativo, que debe configurarse utilizando una combinación de ensamblaje y código C.
Suponiendo que esto es para x86, es probable que puedas ejecutar algo en modo de 16 bits si tienes las opciones de compilador correctas y logras obtener el diseño correcto de tu sector de inicio con la magia del enlazador correcto.
Pero no llegará muy lejos con C
simple (o C ++): necesitará enmascarar las interrupciones muy rápido, y no hay una función C
para eso. Se requiere ensamblaje.
Probablemente esto sea lo mismo para la mayoría de las otras arquitecturas: C y C ++ simplemente no tienen esas características integradas (aunque algunas extensiones de compilador pueden ayudarlo).
Un gran recurso para lo que intenta hacer: OSDev .