I am working on a custom NEWLIB but first I wanted to make sure that NEWLIB compiled for ARM-NONE-EABI works out of the box with my ARM bare-metal Clang/LLVM build and Qemu.
Lets start with a simple main() that includes printf, puts and malloc. The first test is related to malloc, as if your linker script is not setting up your heap properly and providing the heap “end” address as defined in NEWLIB then not much else is going to work (i.e. printf uses malloc). If malloc works, then lets so some printfs including one with a random string. After that lets keep increasing the size of our mallocs till we run out of heap space.
#include <stdio.h> /* printf, scanf, NULL */#include <stdlib.h> /* malloc, free, rand */intmain(){externchar_heap_start;/* Defined by the linker from src/cortex_M3.ld */externchar_heap_end;/* Defined by the linker from src/cortex_M3.Ld. */inti,n;char*buffer;i=43;buffer=(char*)malloc(i);if(buffer==NULL){puts("Malloc failed\n");exit(1);}printf("Printf string\n");for(n=0;n<i;n++){buffer[n]=rand()%26+'a';}buffer[i]='\0';printf("Random string: %s\n",buffer);i=32;do{buffer=realloc(buffer,i);if(buffer==NULL){puts("Out of memory!\n");exit(1);}else{printf("%d bytes @ address 0x%X (Low=0x%X:Hi=0x%X)\n",i,(unsignedint)buffer,(unsignedint)&_heap_start,(unsignedint)&_heap_end);i=i+32;}}while(buffer!=NULL);exit(0);/* cause qemu to exit */return0;}
Easy enough, so lets create a linker script that is geared for a Cortex-M3, the main section to pay attention to in this example is .heap:
Ok, now that we have a linker script that defines our stack and heap properly, lets reuse our startup.c routine for the Cortex-M cores and compile it all with CLang/LLVM and link it with arm-none-eabi-ld: