--- /dev/null
+/*****************************************************************************\r
+ * Copyright (c) 2009 Rowley Associates Limited. *\r
+ * *\r
+ * This file may be distributed under the terms of the License Agreement *\r
+ * provided with this software. *\r
+ * *\r
+ * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE *\r
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *\r
+ *****************************************************************************/\r
+\r
+/*****************************************************************************\r
+ * Preprocessor Definitions\r
+ * ------------------------\r
+ * APP_ENTRY_POINT\r
+ *\r
+ * Defines the application entry point function, if undefined this setting\r
+ * defaults to "main".\r
+ *\r
+ * USE_PROCESS_STACK\r
+ *\r
+ * If defined, thread mode will be configured to use the process stack if\r
+ * the size of the process stack is greater than zero bytes in length.\r
+ *\r
+ * INITIALIZE_STACK\r
+ *\r
+ * If defined, the contents of the stack will be initialized to a the\r
+ * value 0xCC.\r
+ *\r
+ * FULL_LIBRARY\r
+ *\r
+ * If defined then\r
+ * - argc, argv are setup by the debug_getargs.\r
+ * - the exit symbol is defined and executes on return from main.\r
+ * - the exit symbol calls destructors, atexit functions and then debug_exit.\r
+ *\r
+ * If not defined then\r
+ * - argc and argv are zero.\r
+ * - no exit symbol, code loops on return from main.\r
+ *****************************************************************************/\r
+\r
+#ifndef APP_ENTRY_POINT\r
+#define APP_ENTRY_POINT main\r
+#endif\r
+\r
+#ifndef ARGSSPACE\r
+#define ARGSSPACE 128\r
+#endif\r
+\r
+ .global _start\r
+ .syntax unified\r
+ .extern APP_ENTRY_POINT\r
+#ifdef FULL_LIBRARY\r
+ .global exit\r
+#endif\r
+\r
+ .section .init, "ax"\r
+ .code 16\r
+ .align 2\r
+ .thumb_func\r
+\r
+_start:\r
+#ifdef __RAM_BUILD\r
+ ldr r1, =__stack_end__\r
+ mov sp, r1\r
+#endif\r
+#ifdef INITIALIZE_STACK\r
+ mov r2, #0xCC\r
+ ldr r0, =__stack_start__\r
+#ifndef __RAM_BUILD\r
+ mov r1, sp\r
+#endif\r
+ bl memory_set\r
+#endif\r
+\r
+#ifdef USE_PROCESS_STACK\r
+ /* Set up process stack if size > 0 */\r
+ ldr r1, =__stack_process_end__\r
+ ldr r0, =__stack_process_start__\r
+ subs r2, r1, r0\r
+ beq 1f\r
+ msr psp, r1\r
+ mov r2, #2\r
+ msr control, r2\r
+#ifdef INITIALIZE_STACK\r
+ mov r2, #0xCC\r
+ bl memory_set\r
+#endif\r
+1:\r
+#endif\r
+ /* Copy initialised memory sections into RAM (if necessary). */\r
+ ldr r0, =__data_load_start__\r
+ ldr r1, =__data_start__\r
+ ldr r2, =__data_end__\r
+ bl memory_copy\r
+ ldr r0, =__text_load_start__\r
+ ldr r1, =__text_start__\r
+ ldr r2, =__text_end__\r
+ bl memory_copy\r
+ ldr r0, =__fast_load_start__\r
+ ldr r1, =__fast_start__\r
+ ldr r2, =__fast_end__\r
+ bl memory_copy\r
+ ldr r0, =__ctors_load_start__\r
+ ldr r1, =__ctors_start__\r
+ ldr r2, =__ctors_end__\r
+ bl memory_copy\r
+ ldr r0, =__dtors_load_start__\r
+ ldr r1, =__dtors_start__\r
+ ldr r2, =__dtors_end__\r
+ bl memory_copy\r
+ ldr r0, =__rodata_load_start__\r
+ ldr r1, =__rodata_start__\r
+ ldr r2, =__rodata_end__\r
+ bl memory_copy\r
+\r
+ /* Zero the bss. */\r
+ ldr r0, =__bss_start__\r
+ ldr r1, =__bss_end__\r
+ mov r2, #0\r
+ bl memory_set\r
+\r
+ /* Initialise the heap */\r
+ ldr r0, = __heap_start__\r
+ ldr r1, = __heap_end__\r
+ sub r1, r1, r0\r
+ mov r2, #0\r
+ str r2, [r0]\r
+ add r0, r0, #4\r
+ str r1, [r0]\r
+\r
+ /* Call constructors */\r
+ ldr r0, =__ctors_start__\r
+ ldr r1, =__ctors_end__\r
+ctor_loop:\r
+ cmp r0, r1\r
+ beq ctor_end\r
+ ldr r2, [r0]\r
+ add r0, #4\r
+ push {r0-r1}\r
+ blx r2\r
+ pop {r0-r1}\r
+ b ctor_loop\r
+ctor_end:\r
+\r
+ /* Setup initial call frame */\r
+ mov r0, #0\r
+ mov lr, r0\r
+ mov r12, sp\r
+\r
+start:\r
+ /* Jump to application entry point */\r
+#ifdef FULL_LIBRARY\r
+ mov r0, #ARGSSPACE\r
+ ldr r1, =args\r
+ ldr r2, =debug_getargs\r
+ blx r2\r
+ ldr r1, =args\r
+#else\r
+ mov r0, #0\r
+ mov r1, #0\r
+#endif\r
+ ldr r2, =APP_ENTRY_POINT\r
+ blx r2\r
+\r
+#ifdef FULL_LIBRARY\r
+ .thumb_func\r
+exit:\r
+ mov r5, r0 // save the exit parameter/return result\r
+\r
+ /* Call destructors */\r
+ ldr r0, =__dtors_start__\r
+ ldr r1, =__dtors_end__\r
+dtor_loop:\r
+ cmp r0, r1\r
+ beq dtor_end\r
+ ldr r2, [r0]\r
+ add r0, #4\r
+ push {r0-r1}\r
+ blx r2\r
+ pop {r0-r1}\r
+ b dtor_loop\r
+dtor_end:\r
+\r
+ /* Call atexit functions */\r
+ ldr r2, =_execute_at_exit_fns\r
+ blx r2\r
+\r
+ /* Call debug_exit with return result/exit parameter */\r
+ mov r0, r5\r
+ ldr r2, =debug_exit\r
+ blx r2\r
+#endif\r
+\r
+ /* Returned from application entry point, loop forever. */\r
+exit_loop:\r
+ b exit_loop\r
+\r
+memory_copy:\r
+ cmp r0, r1\r
+ beq 2f\r
+ subs r2, r2, r1\r
+ beq 2f\r
+1:\r
+ ldrb r3, [r0]\r
+ add r0, r0, #1\r
+ strb r3, [r1]\r
+ add r1, r1, #1\r
+ subs r2, r2, #1\r
+ bne 1b\r
+2:\r
+ bx lr\r
+\r
+memory_set:\r
+ cmp r0, r1\r
+ beq 1f\r
+ strb r2, [r0]\r
+ add r0, r0, #1\r
+ b memory_set\r
+1:\r
+ bx lr\r
+\r
+#ifdef FULL_LIBRARY\r
+ .bss\r
+args:\r
+ .space ARGSSPACE\r
+#endif\r
+\r