1. Build Tool: ti-cgt-arm_20.2.7.LTS
Перед main загружается из файла
C:\ti\ccs1110\ccs\tools\compiler\ti-cgt-arm_20.2.7.LTS\lib\src\boot_non_cortex_m.asm
asm-функция _c_int00 на строчке 180 (32 BIT STATE BOOT ROUTINE).
Файл boot_non_cortex_m.asm надо немного отредактировать, чтобы при старте cortex a15 процессор не падал в hard fault.
;****************************************************************************
;* BOOT.ASM
;*
;* THIS IS THE INITAL BOOT ROUTINE FOR TMS470 C++ PROGRAMS.
;* IT MUST BE LINKED AND LOADED WITH ALL C++ PROGRAMS.
;*
;* THIS MODULE PERFORMS THE FOLLOWING ACTIONS:
;* 1) ALLOCATES THE STACK AND INITIALIZES THE STACK POINTER
;* 2) CALLS AUTO-INITIALIZATION ROUTINE
;* 3) CALLS THE FUNCTION MAIN TO START THE C++ PROGRAM
;* 4) CALLS THE STANDARD EXIT ROUTINE
;*
;* THIS MODULE DEFINES THE FOLLOWING GLOBAL SYMBOLS:
;* 1) __stack STACK MEMORY AREA
;* 2) _c_int00 BOOT ROUTINE
;*
;****************************************************************************
.armfunc _c_int00
;****************************************************************************
;* 32 BIT STATE BOOT ROUTINE *
;****************************************************************************
.global __stack
;***************************************************************
;* DEFINE THE USER MODE STACK (DEFAULT SIZE IS 512)
;***************************************************************
__stack:.usect ".stack", 0, 4
.global _c_int00
;***************************************************************
;* FUNCTION DEF: _c_int00
;***************************************************************
_c_int00: .asmfunc stack_usage(0)
; Invalidate and Enable Branch Prediction
MOV r0, #0
MCR p15, #0, r0, c7, c5, #6
ISB
MRC p15, #0, r0, c1, c0, #0
ORR r0, r0, #0x00000800
MCR p15, #0, r0, c1, c0, #0
.if __TI_NEON_SUPPORT__ | __TI_VFP_SUPPORT__
;
; Enable Neon/VFP Co-Processor
;
MRC p15, #0, r1, c1, c0, #2 ; r1 = Access Control Register
ORR r1, r1, #(0xf << 20) ; enable full access for p10,11
MCR p15, #0, r1, c1, c0, #2 ; Access Control Register = r1
MOV r1, #0
MCR p15, #0, r1, c7, c5, #4 ; flush prefetch buffer
MOV r0,#0x40000000
FMXR FPEXC, r0 ; Set Neon/VFP Enable bit
;*------------------------------------------------------
;* SETUP PRIVILEGED AND USER MODE ACCESS TO COPROCESSORS
;* 10 AND 11, REQUIRED TO ENABLE NEON/VFP
;* COPROCESSOR ACCESS CONTROL REG
;* BITS [23:22] - CP11, [21:20] - CP10
;* SET TO 0b11 TO ENABLE USER AND PRIV MODE ACCESS
;*------------------------------------------------------
;MRC p15,#0x0,r0,c1,c0,#2
;MOV r3,#0xf00000
;ORR r0,r0,r3
;MCR p15,#0x0,r0,c1,c0,#2
;*------------------------------------------------------
; SET THE EN BIT, FPEXC[30] TO ENABLE NEON AND VFP
;*------------------------------------------------------
;MOV r0,#0x40000000
;FMXR FPEXC,r0
.endif
;*------------------------------------------------------
;* SET TO USER MODE
;*------------------------------------------------------
;
; Change to user mode. It allows for a stack smaller than 64kB.
;
;MRS r0, cpsr
;BIC r0, r0, #0x1F ; CLEAR MODES
;ORR r0, r0, #0x10 ; SET USER MODE
;MSR cpsr_pf, r0
;*------------------------------------------------------
;* INITIALIZE THE USER MODE STACK
;*------------------------------------------------------
;.if __TI_AVOID_EMBEDDED_CONSTANTS
; MOVW sp, __STACK_END
; MOVT sp, __STACK_END
;.else
;LDR sp, c_STACK_END
;.endif
;
; The stack for all the modes (Abort, FIQ, etc.) is set by
; the runtime support library.
;
BIC r0, r0, #0x1F ; system mode
ORR r0, r0, #0x12 ; IRQ mode
MSR cpsr_cf, r0
LDR r13, c_IRQ_STACK_END
ORR r0, r0, #0x1F ; system mode
MSR cpsr_cf, r0
LDR r13, c_SYSTEM_STACK_END
;*------------------------------------------------------
;* Call the __mpu_init hook function.
;*------------------------------------------------------
BL __mpu_init
;*------------------------------------------------------
;* Perform all the required initializations when
;* _system_pre_init() returns non-zero:
;* - Process BINIT Table
;* - Perform C auto initialization
;* - Call global constructors
;*------------------------------------------------------
BL _system_pre_init
CMP R0, #0
BEQ bypass_auto_init
BL __TI_auto_init
bypass_auto_init:
;*------------------------------------------------------
;* CALL APPLICATION
;*------------------------------------------------------
BL _args_main
;*------------------------------------------------------
;* IF APPLICATION DIDN'T CALL EXIT, CALL EXIT(1)
;*------------------------------------------------------
MOV R0, #1
BL exit
;*------------------------------------------------------
;* DONE, LOOP FOREVER
;*------------------------------------------------------
L1: B L1
.endasmfunc
;***************************************************************
;* CONSTANTS USED BY THIS MODULE
;***************************************************************
;.if !__TI_AVOID_EMBEDDED_CONSTANTS
c_SYSTEM_STACK_END .long __STACK_END
c_IRQ_STACK_END .long __STACK_END - 0x400
;.endif
;******************************************************
;* UNDEFINED REFERENCES *
;******************************************************
.global __STACK_END
.global _system_pre_init
.global __TI_auto_init
.global _args_main
.global exit
.global __mpu_init
.end
Links:
2. Build tool: Linaro GNU v7.2.1. Файл в сконструированном мастером проекте startup_ARMCA15.S.
@
@ startup_ARMCA15.S - Init code routine for Cortex A15 cores and Linaro baremetal
@
@****************************** Global Symbols*******************************
.global Entry
.global __stack
.global __bss_start__
.global __bss_end__
.global start_boot
@************************ Internal Definitions ******************************
@
@ to set the mode bits in CPSR for different modes
@
.set MODE_USR, 0x10
.set MODE_FIQ, 0x11
.set MODE_IRQ, 0x12
.set MODE_SVC, 0x13
.set MODE_ABT, 0x17
.set MODE_UND, 0x1B
.set MODE_SYS, 0x1F
.equ I_F_BIT, 0xC0
@**************************** Code Section ***********************************
.text
@
@ This code is assembled for ARM instructions
@
.code 32
@******************************************************************************
@
@******************************************************************************
@
@ The reset handler sets up the stack pointers for all the modes. The FIQ and
@ IRQ shall be disabled during this. Then clears the BSS section, enters the
@ main function.
Entry:
@ Invalidate and Enable Branch Prediction
MOV r0, #0
MCR p15, #0, r0, c7, c5, #6
ISB
MRC p15, #0, r0, c1, c0, #0
ORR r0, r0, #0x00000800
MCR p15, #0, r0, c1, c0, #0
.if __ARM_PCS_VFP == 1
@
@ Enable Neon/VFP Co-Processor
@
MRC p15, #0, r1, c1, c0, #2 @ r1 = Access Control Register
ORR r1, r1, #(0xf << 20) @ enable full access for p10,11
MCR p15, #0, r1, c1, c0, #2 @ Access Control Register = r1
MOV r1, #0
MCR p15, #0, r1, c7, c5, #4 @ flush prefetch buffer
MOV r0,#0x40000000
FMXR FPEXC, r0 @ Set Neon/VFP Enable bit
.endif
MRS r0, cpsr
ORR r0, r0, #192
MSR cpsr, r0
@
@ The stack for all the modes (Abort, FIQ, etc.) is set by
@ the runtime support library.
@
BIC r0, r0, #0x1F
ORR r0, r0, #0x12
MSR cpsr_cf, r0
LDR r13, = __StackMp
ORR r0, r0, #0x1F
MSR cpsr_cf, r0
LDR r13, = __StackTop
@
@ Set up the Vector Base Address Regsiter
@
LDR r0, = __isr_vector
MCR p15, 0, r0, c12, c0, 0 @ Write VBAR Register
.if USERMODE == 1
@
@ Change to user mode. It allows for a stack smaller than 64kB.
@
MSR cpsr_c, #MODE_USR|I_F_BIT @ change to user mode
.endif
@
@ The BSS section is cleared by the runtime support library
@
@
@ Enter the main function.
@ The symbol _start is the entry point for the runtime support library
@
Enter_BootLoader:
LDR r10, = _start @ Get the address of _start
MOV lr,pc @ Dummy return
BX r10 @ Branch to main
SUB pc, pc, #0x08 @ looping
@
@ Set the Stack space here
@
.section .stack
.align 4
.globl __StackBase
.globl __StackLimit
__StackLimit:
@ .space 0x400 @ the stack size is set by the linker script
.size __StackLimit, . - __StackLimit
__StackBase:
.size __StackBase, . - __StackBase
@
@ Set the Heap space here
@
.section .heap
.align 4
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
@ .space 0x400 @ the heap size is set by the linker script
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
@
@ Set the Interrupt vector table here
@
.section .isr_vector
.align 4
.globl __isr_vector
__isr_vector:
LDR pc, [pc,#24] @ 0x00 Reset
LDR pc, = UndefInstHandler @ 0x04 Undefined instruction
LDR pc, = SVC_Handler @ 0x08 Supervisor
LDR pc, = AbortHandler @ 0x0C Prefetch abort
LDR pc, = AbortHandler @ 0x10 Data abort
LDR pc, = AbortHandler @ 0x14 not used
LDR pc, = IRQHandler @ 0x18 IRQ
LDR pc, = FIQHandler @ 0x1C FIQ
.long Entry
.long 0
.long SVC_Handler
.long 0
.long 0
.long 0
.long 0
.long 0
@
@ End of the file
@
.end
Stack:
1) Устройство Стека для Intel386 https://habr.com/ru/articles/675522/
2) Загрузка ОС на ARM https://habr.com/ru/companies/aladdinrd/articles/338806/
3) Как защититься от переполнения стека (на Cortex M)? https://habr.com/ru/articles/425071/
4) Как работает stack trace на ARM https://habr.com/ru/companies/embox/articles/424365/
5) Одна маленькая загадка про Cortex-M https://habr.com/ru/articles/224101/
Interrupts:
1) Что необходимо знать, чтобы написать свою Embedded RTOS (часть 1) https://habr.com/ru/articles/598693/
2) Тайны пингвина: как работают исключения и прерывания в Linux? https://habr.com/ru/companies/timeweb/articles/780082/
3) Динамическое управление прерываниями в ARM https://habr.com/ru/articles/275351/
4) Прерывания в конвейеризированных процессорах https://habr.com/ru/articles/188002/