Пример минимального запуска Newlib
Здесь я приведу высоко автоматизированный и документированный пример, который показывает newlib в действии в QEMU .
С newlib вы реализуете свои собственные системные вызовы для вашей платформы baremetal.
Например, в приведенном выше примере у нас есть пример программы exit.c
:
#include <stdio.h>
#include <stdlib.h>
void main(void) {
exit(0);
}
и в отдельном C-файле common.c
мы реализуем exit
с полухостингом ARM :
void _exit(int status) {
__asm__ __volatile__ ("mov r0, #0x18; ldr r1, =#0x20026; svc 0x00123456");
}
Другие типичные системные вызовы, которые вы реализуете:
write
выводить результаты на хост. Это можно сделать с помощью:
- больше полухостинга
- аппаратное обеспечение UART
brk
для malloc
.
Легко на голом металле, так как нам не нужно заботиться о подкачке!
TODO Интересно, реально ли достичь выполнения системных вызовов с упреждающим планированием, не вдаваясь в полноценную RTOS, такую как Zephyr или FreeRTOS .
Самое замечательное в Newlib - это то, что он реализует все не связанные с ОС вещи, подобные string.h
вам, и позволяет вам реализовывать только заглушки ОС.
Кроме того, вам не нужно реализовывать все заглушки, а только те, которые вам понадобятся. Например, если ваша программа нужна только вам exit
, вам не нужно предоставлять print
.
В исходном дереве Newlib уже есть некоторые реализации, в том числе реализация ARM-полухостинга newlib/libc/sys/arm
, но по большей части вы должны реализовать свою собственную. Это, однако, обеспечивает прочную основу для этой задачи.
Самый простой способ настроить Newlib - это создать собственный компилятор с помощью crosstool-NG, вам просто нужно сообщить ему, что вы хотите использовать Newlib в качестве библиотеки C. Моя установка обрабатывает это автоматически для вас с помощью этого скрипта , который использует конфиги newlib, представленные на crosstool_ng_config
.
Я думаю, что C ++ также будет работать, но TODO протестирует его.