/* startup code for Cortex-M3*/
#define USE_LIBC 1
#pragma GCC optimize("Os")

extern unsigned long _etext, _sdata, _edata, _end;
extern void main(void);
extern void __libc_init_array(void);

/* come here on power up, copy the .data and clear the .bss */
 __attribute__ ((noreturn)) void _start(void){
	unsigned long *pulSrc, *pulDest;

	/* Copy the data segment initializers from flash to SRAM */
	pulSrc  = &_etext;
	pulDest = &_sdata;

	for(; pulDest < &_edata; )
		*(pulDest++) = *(pulSrc++);
	/* Zero fill the bss segment. */
	for(; pulDest < &_end; )
		*(pulDest++) = 0;
#ifdef USE_LIBC
	/* initialize the libc */
	__libc_init_array();
#endif
	/* jump to user program */
	while (1)
		main();
}

#ifdef USE_LIBC
#include <sys/errno.h>
extern unsigned int _stack_bottom;
#define RAM_END (void*)&_stack_bottom
 /*
  * sbrk -- changes heap size size. Get nbytes more
  *         RAM. We just increment a pointer in what's
  *         left of memory on the board.
  */
void * _sbrk(nbytes)
      int nbytes;
 {
   static void * heap_ptr = (void*) &_end;
   void *        base;

   if (heap_ptr + nbytes < RAM_END) {
     base = heap_ptr;
     heap_ptr += nbytes;
     return (base);
   }  
   errno = ENOMEM;
   return ((void*)-1);
 }
#endif