-march=rv32i Включение набора команд процессора RV32I, базовый набор даже без умножения
-mabi=ilp32 Принудительное включение 32 битных вычислений, основанное только на integer (i), в том числи длинные целые long тоже 32 бит (l), и указатели (p32), без поддержки FPU, которое эмулируется программно
-nostdlib Не подключать библиотеку stdlib
-T linker.ld Использовать конфигурации линковщика из файла linked.ld (можно задать самому)
-Os Оптимизация по размеру кода, уменьшить код до предела
main.c и -o main.elf Входящий и исходящий готовый файл
Опционально:
objcopy Извлечение бинарного кода из main.elf в файл main.bin для запуска на эмуляторах
objdump Для того чтобы посмотреть ассемблерный листинг
§ main.c
Ниже представлен код, который выведет "Hello World" в условный адрес 0x10000000:
__attribute__((section(".text.entry")))
void _start()
{
asm("li sp, 0x10000");
char *str = "Hello World!\n";
volatile char *uart = (char *)0x10000000;
while (*str) { *uart = *str; str++; }
for (;;);
}
В коде принудительно устанавливается высота стека, хотя этим и должна заниматься ОС, но так как код запускается на чистом "железе" с нуля, то надо заполнять этот момент самостоятельно.