mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-10-26 23:36:32 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			265 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*****************************************************************************
 | |
|  * 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
 | |
|   
 | |
|                   
 |