Ejemplo ejecutable mínimo de Newlib
Aquí proporciono un ejemplo altamente automatizado y documentado que muestra newlib en acción en QEMU .
Con newlib, implementa sus propias llamadas al sistema para su plataforma baremetal.
Por ejemplo, en el ejemplo anterior, tenemos un programa de ejemplo exit.c
:
#include <stdio.h>
#include <stdlib.h>
void main(void) {
exit(0);
}
y en un archivo C separado common.c
, implementamos exit
con semihosting ARM :
void _exit(int status) {
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
}
Los otros syscalls típicos que implementará son:
write
para dar resultados al host. Esto se puede hacer con:
- más semihosting
- un hardware UART
brk
para malloc
.
¡Fácil en metal desnudo, ya que no tenemos que preocuparnos por la paginación!
TODO Me pregunto si es realista alcanzar la ejecución preventiva de syscalls de programación sin entrar en un RTOS completo como Zephyr o FreeRTOS .
Lo bueno de Newlib es que implementa todas las cosas que no son específicas del sistema operativo, como string.h
usted, y le permite implementar solo los apéndices del sistema operativo.
Además, no tiene que implementar todos los apéndices, sino solo los que necesitará. Por ejemplo, si su programa solo lo necesita exit
, entonces no tiene que proporcionar a print
.
El árbol fuente de Newlib ya tiene algunas implementaciones, incluida una implementación de semihosting ARM newlib/libc/sys/arm
, pero en su mayor parte debe implementar la suya propia. Sin embargo, proporciona una base sólida para la tarea.
La forma más fácil de configurar Newlib es compilando su propio compilador con crosstool-NG, solo tiene que decirle que desea usar Newlib como la biblioteca C. Mi configuración lo maneja automáticamente con este script , que usa las configuraciones newlib presentes encrosstool_ng_config
.
Creo que C ++ también funcionará, pero TODO lo prueba.