1/* 2 * Copyright (C) 2004-2007 Atmel Corporation 3 * 4 * This file is subject to the terms and conditions of the GNU Lesser General 5 * Public License. See the file "COPYING.LIB" in the main directory of this 6 * archive for more details. 7 * 8 * When we enter _start, the stack looks like this: 9 * argc argument counter 10 * argv[0] pointer to program name 11 * argv[1..argc-1] pointers to program args 12 * NULL 13 * env[0..N] pointers to environment variables 14 * NULL 15 * 16 * r12 contains a function pointer to be registered with `atexit'. 17 * This is how the dynamic linker arranges to have DT_FINI functions 18 * called for shared libraries that have been loaded before this 19 * code runs. 20 * 21 * We're going to call the following function: 22 * __uClibc_main(int (*main)(int, char **, char **), int argc, 23 * char **argv, void (*app_init)(void), void (*app_fini)(void), 24 * void (*rtld_fini)(void), void *stack_end) 25 * 26 * So we need to set up things as follows: 27 * r12 = address of main 28 * r11 = argc 29 * r10 = &argv[0] 30 * r9 = address of _init 31 * r8 = address of _fini 32 * sp[0] = whatever we got passed in r12 33 */ 34 35#include <features.h> 36 37 .text 38 .global _start 39 .type _start, @function 40_start: 41 /* Clear the frame pointer and link register since this is the outermost frame. */ 42 mov r7, 0 43 mov lr, 0 44 45 ld.w r11, sp++ /* argc */ 46 mov r10, sp /* &argv[0] */ 47 48 st.w --sp, r10 /* stack_end */ 49 st.w --sp, r12 /* rtld_fini */ 50 51#ifdef __PIC__ 52 lddpc r6, .L_GOT 53.L_RGOT: 54 rsub r6, pc 55 lda.w r9, _init 56 lda.w r8, _fini 57 lda.w r12, main 58 59 /* Ok, now run uClibc's main() -- should not return */ 60 call __uClibc_main 61 62 .align 2 63.L_GOT: 64 .long .L_RGOT - _GLOBAL_OFFSET_TABLE_ 65#else 66 lddpc r9, __init_addr /* app_init */ 67 lddpc r8, __fini_addr /* app_fini */ 68 lddpc r12, __main_addr /* main */ 69 70 /* Ok, now run uClibc's main() -- should not return */ 71 lddpc pc, ___uClibc_main_addr 72 73 .align 2 74__init_addr: 75 .long _init 76__fini_addr: 77 .long _fini 78__main_addr: 79 .long main 80___uClibc_main_addr: 81 .long __uClibc_main 82#endif 83 .size _start, . - _start 84 85 /* 86 * The LSB says we need this. 87 */ 88 .section ".note.ABI-tag", "a" 89 .align 4 90 .long 2f - 1f /* namesz */ 91 .long 4f - 3f /* descsz */ 92 .long 1 /* type */ 931: .asciz "GNU" /* name */ 942: .align 4 953: .long 0 /* Linux executable */ 96 .long 2,6,0 /* Earliest compatible kernel */ 974: .align 4 98