/***************************************************************************** * Copyright (c) 2001, 2002 Rowley Associates Limited. * * * * This file may be distributed under the terms of the License Agreement * * provided with this software. * * * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE * * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * *****************************************************************************/ .section .init, "ax" .code 32 .align 0 .weak _start .global __start .global __gccmain .extern main .extern exit /***************************************************************************** * Function : _start * * Description : Main entry point and startup code for C system. * *****************************************************************************/ _start: __start: mrs r0, cpsr bic r0, r0, #0x1F /* Setup stacks */ orr r1, r0, #0x1B /* Undefined mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_und_end__ orr r1, r0, #0x17 /* Abort mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_abt_end__ orr r1, r0, #0x12 /* IRQ mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_irq_end__ orr r1, r0, #0x11 /* FIQ mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_fiq_end__ orr r1, r0, #0x13 /* Supervisor mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_svc_end__ #ifdef SUPERVISOR_START /* Start application in supervisor mode */ ldr r1, =__stack_end__ /* Setup user/system mode stack */ mov r2, sp stmfd r2!, {r1} ldmfd r2, {sp}^ #else /* Start application in system mode */ orr r1, r0, #0x1F /* System mode */ msr cpsr_cxsf, r1 ldr sp, =__stack_end__ #endif /* Copy from initialised data section to data section (if necessary). */ ldr r0, =__data_load_start__ ldr r1, =__data_start__ cmp r0, r1 beq copy_data_end ldr r2, =__data_end__ subs r2, r2, r1 beq copy_data_end copy_data_loop: ldrb r3, [r0], #+1 strb r3, [r1], #+1 subs r2, r2, #1 bne copy_data_loop copy_data_end: /* Copy from initialised text section to text section (if necessary). */ ldr r0, =__text_load_start__ ldr r1, =__text_start__ cmp r0, r1 beq copy_text_end ldr r2, =__text_end__ subs r2, r2, r1 beq copy_text_end copy_text_loop: ldrb r3, [r0], #+1 strb r3, [r1], #+1 subs r2, r2, #1 bne copy_text_loop copy_text_end: /* Copy from initialised fast_text section to fast_text section (if necessary). */ ldr r0, =__fast_load_start__ ldr r1, =__fast_start__ cmp r0, r1 beq copy_fast_end ldr r2, =__fast_end__ subs r2, r2, r1 beq copy_fast_end copy_fast_loop: ldrb r3, [r0], #+1 strb r3, [r1], #+1 subs r2, r2, #1 bne copy_fast_loop copy_fast_end: /* Zero the bss. */ ldr r0, =__bss_start__ ldr r1, =__bss_end__ mov r2, #0 zero_bss_loop: cmp r0, r1 beq zero_bss_end strb r2, [r0], #+1 b zero_bss_loop zero_bss_end: #ifdef CHECK /* Check data */ ldr r0, =__data_load_start__ ldr r1, =__data_start__ cmp r0, r1 beq check_data_end ldr r2, =__data_end__ subs r2, r2, r1 beq check_data_end check_data_loop: ldrb r3, [r0], #+1 ldrb r4, [r1], #+1 cmp r3, r4 bne data_error_loop subs r2, r2, #1 bne check_data_loop check_data_end: /* Check text */ ldr r0, =__text_load_start__ ldr r1, =__text_start__ cmp r0, r1 beq check_text_end ldr r2, =__text_end__ subs r2, r2, r1 beq check_text_end check_text_loop: ldrb r3, [r0], #+1 ldrb r4, [r1], #+1 cmp r3, r4 bne text_error_loop subs r2, r2, #1 bne check_text_loop check_text_end: /* Check fast */ ldr r0, =__fast_load_start__ ldr r1, =__fast_start__ cmp r0, r1 beq check_fast_end ldr r2, =__fast_end__ subs r2, r2, r1 beq check_fast_end check_fast_loop: ldrb r3, [r0], #+1 ldrb r4, [r1], #+1 cmp r3, r4 bne fast_error_loop subs r2, r2, #1 bne check_fast_loop check_fast_end: /* Check bss */ ldr r0, =__bss_start__ ldr r1, =__bss_end__ mov r2, #0 check_bss_loop: cmp r0, r1 beq check_bss_end ldrb r2, [r0], #+1 cmp r2, #0 bne bss_error_loop b check_bss_loop check_bss_end: #endif /* Initialise the heap */ ldr r0, = __heap_start__ ldr r1, = __heap_end__ sub r1, r1, r0 /* r1 = r1-r0 */ mov r2, #0 str r2, [r0], #+4 /* *r0++ = 0 */ str r1, [r0] /* *r0 = __heap_end__ - __heap_start__ */ /* Call constructors */ ldr r0, =__ctors_start__ ldr r1, =__ctors_end__ ctor_loop: cmp r0, r1 beq ctor_end ldr r2, [r0], #+4 stmfd sp!, {r0-r1} mov lr, pc mov pc, r2 ldmfd sp!, {r0-r1} b ctor_loop ctor_end: /* Setup initial call frame */ mov lr, #4 mov r12, sp stmfd sp!, {r11-r12, lr-pc} sub r11, r12, #0x00000004 start: /* Jump to main entry point */ mov r0, #0 mov r1, #0 ldr r2, =main mov lr, pc #ifdef __ARM_ARCH_3__ mov pc, r2 #else bx r2 #endif /* Call destructors */ ldr r0, =__dtors_start__ ldr r1, =__dtors_end__ dtor_loop: cmp r0, r1 beq dtor_end ldr r2, [r0], #+4 stmfd sp!, {r0-r1} mov lr, pc mov pc, r2 ldmfd sp!, {r0-r1} b dtor_loop dtor_end: /* Return from main, loop forever. */ exit_loop: b exit_loop #ifdef CHECK data_error_loop: b data_error_loop text_error_loop: b text_error_loop fast_error_loop: b fast_error_loop bss_error_loop: b bss_error_loop #endif