.extern system_init .extern __bss_start .extern __bss_end .extern vFreeRTOS_ISR .extern vPortYieldProcessor .extern DisableInterrupts .extern FreeRTOS_Main .section .init .globl _start ;; _start: ;@ All the following instruction should be read as: ;@ Load the address at symbol into the program counter. ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi! ;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset! ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb! ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode. ldr pc,prefetch_handler ;@ Prefetch/abort handler. ldr pc,data_handler ;@ Data abort handler/ ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler. ldr pc,irq_handler ;@ IRQ handler ldr pc,fiq_handler ;@ Fast interrupt handler. ;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses reset_handler: .word reset undefined_handler: .word undefined_instruction swi_handler: .word vPortYieldProcessor prefetch_handler: .word prefetch_abort data_handler: .word data_abort unused_handler: .word unused irq_handler: .word vFreeRTOS_ISR fiq_handler: .word fiq reset: ;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000 mov r0,#0x8000 ;@ Store the source pointer mov r1,#0x0000 ;@ Store the destination pointer. ;@ Here we copy the branching instructions ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0 stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1 ;@ So the branches get the correct address we also need to copy our vector table! ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented. stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data. ;@ Set up the various STACK pointers for different CPU modes ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) mov r0,#0xD2 msr cpsr_c,r0 mov sp,#0x8000 ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) mov r0,#0xD1 msr cpsr_c,r0 mov sp,#0x4000 ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) mov r0,#0xD3 msr cpsr_c,r0 mov sp,#0x8000000 ldr r0, =__bss_start ldr r1, =__bss_end mov r2, #0 zero_loop: cmp r0,r1 it lt strlt r2,[r0], #4 blt zero_loop bl DisableInterrupts ;@ mov sp,#0x1000000 b FreeRTOS_Main ;@ We're ready?? Lets start main execution! .section .text undefined_instruction: b undefined_instruction prefetch_abort: b prefetch_abort data_abort: b data_abort unused: b unused fiq: b fiq hang: b hang