📄 boot.s
字号:
;----------------------------------------------------------------------------------------------
;- ARM AT91RM9200 BOOT CODE
;----------------------------------------------------------------------------------------------
;- File name: Boot.s
;-
;-
;- Init stack of each mode
;-
;- 2006.03.09
;----------------------------------------------------------------------------------------------
INCLUDE AT91RM9200.INC
;----------------------------------------------------------------------------------------------
;- Const definition
;----------------------------------------------------------------------------------------------
FIQ_STACK_SIZE EQU 0x100
IRQ_STACK_SIZE EQU 0x100
UND_STACK_SIZE EQU 0x40
ABT_STACK_SIZE EQU 0x40
SVC_STACK_SIZE EQU 0x40
USR_STACK_SIZE EQU 0x40
CP_ICACHE_BIT EQU (0x1:SHL:12)
CP_DCACHE_BIT EQU (0x1:SHL:2)
;----------------------------------------------------------------------------------------------
;- Allocate stack for each mode
;----------------------------------------------------------------------------------------------
AREA |C$$Stack|, DATA, READWRITE
FIQ_Stack_Bottom DCD 0xCDCDCDCD
SPACE (FIQ_STACK_SIZE - 0x04)
FIQ_Stack_Top EQU (FIQ_Stack_Bottom + FIQ_STACK_SIZE)
IRQ_Stack_Bottom DCD 0xCDCDCDCD
SPACE (IRQ_STACK_SIZE - 0x04)
IRQ_Stack_Top EQU (IRQ_Stack_Bottom + IRQ_STACK_SIZE)
ABT_Stack_Bottom DCD 0xCDCDCDCD
SPACE (ABT_STACK_SIZE - 0x04)
ABT_Stack_Top EQU (ABT_Stack_Bottom + ABT_STACK_SIZE)
UND_Stack_Bottom DCD 0xCDCDCDCD
SPACE (UND_STACK_SIZE - 0x04)
UND_Stack_Top EQU (UND_Stack_Bottom + UND_STACK_SIZE)
SVC_Stack_Bottom DCD 0xCDCDCDCD
SPACE (SVC_STACK_SIZE - 0x04)
SVC_Stack_Top EQU (SVC_Stack_Bottom + SVC_STACK_SIZE)
USR_Stack_Bottom DCD 0xCDCDCDCD
SPACE (USR_STACK_SIZE - 0x04)
USR_Stack_Top EQU (USR_Stack_Bottom + USR_STACK_SIZE)
;----------------------------------------------------------------------------------------------
;- Handle expection without notify OS
;----------------------------------------------------------------------------------------------
;-
;- This macro offers a ordinary way of handling exception
;-
;----------------------------------------------------------------------------------------------
MACRO
EXCPHANDLER $c_handler, $s_handler
IMPORT $c_handler
EXPORT $s_handler
$s_handler
;----------------------------------------------------------------------------------------------
;- Save context
;----------------------------------------------------------------------------------------------
;-
;- Just save r0 to r12 in the expection mode stack
;-
;----------------------------------------------------------------------------------------------
stmfd sp!, {r0-r7, lr}
;----------------------------------------------------------------------------------------------
;- Hadle Interrupt
;----------------------------------------------------------------------------------------------
;-
;- Jump to c intterupt handler
;- All this c code is running without open opening IRQ and FIQ in core
;-
;----------------------------------------------------------------------------------------------
ldr r0, =$c_handler
mov lr, pc
bx r0
;----------------------------------------------------------------------------------------------
;- Mark the end of intterupt on AIC
;----------------------------------------------------------------------------------------------
ldr r0, =AT91C_BASE_AIC
str r0, [r0, #AIC_EOICR]
;----------------------------------------------------------------------------------------------
;- Restore context from stack
;----------------------------------------------------------------------------------------------
ldmfd sp!, {r0-r7, pc}^
MEND
;----------------------------------------------------------------------------------------------
;- Entry point of Boot code
;----------------------------------------------------------------------------------------------
;-
;- _main & __main was exported so that c runtime lib would not be linked in
;-
;----------------------------------------------------------------------------------------------
AREA BOOT, CODE, READONLY
CODE32
ENTRY
IMPORT UndExcp
IMPORT SwiExcp
IMPORT PreAbtExcp
IMPORT DataAbtExcp
IMPORT AT91F_LowLevel_Init
EXPORT _main
EXPORT __main
EXPORT __BOOT
_main
__main
__BOOT
;----------------------------------------------------------------------------------------------
;- Exception vectors (Before Remap)
;----------------------------------------------------------------------------------------------
;-
;- These vector locate at address 0x00000000 before remap.(or other address where codes are
;- download) The Reset Vector requires to be in relative addressing mode in order to guarantee
;- a valid jump. For the moment, if an exception occurs, this would result in an infinite loop.
;-
;----------------------------------------------------------------------------------------------
b StartUpInit
b .
b .
b .
b .
b .
b .
b .
;----------------------------------------------------------------------------------------------
;- Exception vectors (after remap execution)
;----------------------------------------------------------------------------------------------
;-
;- After remap the following vectors will be relocated to adress 0x00000000, that is the real
;- active vector when running user programme. A RELATIVE addressing is FORBIDDEN, in order to
;- guarantee a valid jump. Absolute exception handler address are stored in a defined PC
;- relative offset.
;-
;----------------------------------------------------------------------------------------------
Vec
ldr pc, ResVec
ldr pc, UndVec
ldr pc, SwiVec
ldr pc, PreVec
ldr pc, AbtVec
nop
ldr pc, [pc, #-0xF20]
nop ;- Not defined for future FIQ use
ResVec DCD StartUpInit
UndVec DCD UndHandler
SwiVec DCD SwiHandler
PreVec DCD PreAbtHandler
AbtVec DCD DataAbtHandler
VecEnd
EXCPHANDLER UndExcp, UndHandler
EXCPHANDLER SwiExcp, SwiHandler
EXCPHANDLER PreAbtExcp, PreAbtHandler
EXCPHANDLER DataAbtExcp, DataAbtHandler
;----------------------------------------------------------------------------------------------
;- Start Up Initialization
;----------------------------------------------------------------------------------------------
;-
;- When system startup, There are some neccessery initialization, includes:
;- Stack Init, Low Level(hardware)Init. And I-Chache should also be enabled here. Here, Low
;- Level Init refers initialization of EBI, RAM, FLASH, AIC and PMC, which are performed in
;- C-function AT91F_LowLevel_Init.
;-
;----------------------------------------------------------------------------------------------
CacheBit
DCD (CP_ICACHE_BIT:OR:CP_DCACHE_BIT)
StartUpInit
IF AT91RM9200_CACHE_EN > 0
ldr r1, CacheBit
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
ELSE
ldr r1, CacheBit
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
ENDIF ; AT91RM9200_CACHE_EN
msr CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT
ldr r0, =FIQ_Stack_Top
bic r0, r0, #0x03
mov sp, r0
msr CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT
ldr r0, =IRQ_Stack_Top
bic r0, r0, #0x03
mov sp, r0
msr CPSR_c, #ARM_MODE_ABORT:OR:I_BIT:OR:F_BIT
ldr r0, =ABT_Stack_Top
bic r0, r0, #0x03
mov sp, r0
msr CPSR_c, #ARM_MODE_UNDEF:OR:I_BIT:OR:F_BIT
ldr r0, =UND_Stack_Top
bic r0, r0, #0x03
mov sp, r0
msr CPSR_c, #ARM_MODE_SYS:OR:I_BIT:OR:F_BIT
ldr r0, =USR_Stack_Top
bic r0, r0, #0x03
mov sp, r0
msr CPSR_c, #ARM_MODE_SVC
ldr r0, =SVC_Stack_Top
bic r0, r0, #0x03
mov sp, r0
ldr r0, =AT91F_LowLevel_Init
mov lr, pc
bx r0
;----------------------------------------------------------------------------------------------
;- Code Recompose
;----------------------------------------------------------------------------------------------
;-
;- After StartUp initialization, programe Reset interrupt vectors, copy itself to RAM, and
;- clear ZI section before branch to C code main function .
;-
;----------------------------------------------------------------------------------------------
IMPORT |Image$$RO$$Base|
IMPORT |Image$$RO$$Limit|
IMPORT |Image$$RW$$Base|
IMPORT |Image$$RW$$Limit|
IMPORT |Image$$ZI$$Base|
IMPORT |Image$$ZI$$Limit|
ldr r0, =|Image$$RO$$Base|
ldr r1, =|Image$$RO$$Limit|
ldr r2, =|Image$$RW$$Base|
ldr r3, =|Image$$RW$$Limit|
ldr r4, =|Image$$ZI$$Base|
ldr r5, =|Image$$ZI$$Limit|
add r6, pc, #-(8 + . - __BOOT)
sub r7, r1, r0
add r7, r6, r7
cmp r0, r6
beq RWInit
ROCopy
cmp r0, r1
ldrne r12, [r6], #4
strne r12, [r0], #4
bne ROCopy
RWInit
cmp r7, r2
beq ZIClear
RWCopy
cmp r2, r3
ldrne r12, [r7], #4
strne r12, [r2], #4
bne RWCopy
ZIClear
mov r12, #0
cmp r4, r5
strne r12, [r4], #4
bne ZIClear
;----------------------------------------------------------------------------------------------
;- Jump to new address
;----------------------------------------------------------------------------------------------
;-
;- After the whole image has been copied to RAM, jump to the new code region
;- As the new region is independent from the loaded region, remap command will
;- not affect the running code
;-
;----------------------------------------------------------------------------------------------
; ldr r0,
;----------------------------------------------------------------------------------------------
;- Perform Remap command
;----------------------------------------------------------------------------------------------
;-
;- Remap command should be performed in order to set address 0 writable
;- before register own exception entry
;-
;----------------------------------------------------------------------------------------------
;----------------------------------------------------------------------------------------------
;- Vector Rebuilt
;----------------------------------------------------------------------------------------------
;-
;- Register own exception entry after remaped internal RAM to address 0
;-
;----------------------------------------------------------------------------------------------
mov r0, #0
ldr r1, =Vec
ldr r2, =VecEnd
VectorCopy
cmp r1, r2
ldrcc r12, [r1], #4
strcc r12, [r0], #4
bcc VectorCopy
;----------------------------------------------------------------------------------------------
;- Branch on C code main function
;----------------------------------------------------------------------------------------------
;-
;- Branch must be performed by an interworking call as either an ARM or Thumb
;- main C function must be supported. This makes the code not position-
;- independant.
;-
;----------------------------------------------------------------------------------------------
IMPORT main
ldr r0, =main
mov lr, pc
bx r0
;----------------------------------------------------------------------------------------------
;- End
;----------------------------------------------------------------------------------------------
;-
;- If programe returns form main funtion, it must be halted here
;-
;----------------------------------------------------------------------------------------------
End
b End
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -