AT91RM9200启动代码start.s解读与学习笔记(1)

这里我用到的汇编代码是来自YL9200开发板的资料,先提出该汇编文件:

	INCLUDE   AT91RM9200.inc

_STACK_BASEADDRESS	EQU 0x21ff8000
_MMUTT_STARTADDRESS	EQU 0x21ff8000
_ISR_STARTADDRESS	EQU 0x21ffff00

;Pre-defined constants
USERMODE    EQU 	0x10
FIQMODE     EQU 	0x11
IRQMODE     EQU 	0x12
SVCMODE     EQU 	0x13
ABORTMODE   EQU 	0x17
UNDEFMODE   EQU 	0x1b
MODEMASK    EQU 	0x1f
NOINT       EQU 	0xc0
I_BIT	EQU	0x80
F_BIT	EQU	0x40
T_BIT	EQU	0x20

	AREA	reset, CODE, READONLY
	
	ENTRY
	
	EXPORT	__ENTRY
__ENTRY	
ResetEntry
	b	ResetHandler
	ldr	pc, =HandlerUndef		;handler for Undefined mode
	ldr	pc, =HandlerSWI			;handler for SWI interrupt
	ldr	pc, =HandlerPabort		;handler for PAbort
	ldr	pc, =HandlerDabort		;handler for DAbort
	ldr	pc, =.					;reserved
	ldr	pc, =HandlerIRQ			;handler for IRQ interrupt
	;ldr	pc, [pc,#-0xF20]		;IRQ : read the AIC
	ldr	pc, =HandlerFIQ			;handler for FIQ interrupt
	
	EXPORT	this_machine_ip
this_machine_ip	DCD	(192<<24)|(168<<16)|(2<<8)|(223)

    	MACRO
$HandlerLabel HANDLER $HandleLabel

$HandlerLabel
	sub	sp, sp, #4			;decrement sp(to store jump address)
	stmfd	sp!, {r0}		;PUSH the work register to stack(lr does't push because it return to original address)
	ldr	r0, =$HandleLabel	;load the address of HandleXXX to r0
	ldr	r0, [r0]			;load the contents(service routine start address) of HandleXXX
	str	r0, [sp, #4]      	;store the contents(ISR) of HandleXXX to stack
	ldmfd	sp!, {r0, pc}	;POP the work register and pc(jump to ISR)
	MEND

	LTORG   
HandlerFIQ      HANDLER HandleFIQ
HandlerIRQ      HANDLER HandleIRQ
HandlerUndef    HANDLER HandleUndef
HandlerSWI      HANDLER HandleSWI
HandlerDabort   HANDLER HandleDabort
HandlerPabort   HANDLER HandlePabort

IsrIRQ
	sub	sp, sp, #4       ;reserved for PC
	stmfd	sp!,{r8-r9}
	
	ldr	r9, =AT91C_BASE_AIC
	mov	r8, r9
	ldr	r9, [r9, #AIC_ISR]
	and	r9, r9, #0x1f
	add	r8, r8, r9, lsl #2
	ldr	r8, [r8, #AIC_SVR]
	str	r8, [sp, #8]
	ldmfd	sp!,{r8-r9,pc}	

; * the actual reset code

ResetHandler
	;Set up User Mode, set User Mode Stack and disable interrupts	
	msr	CPSR_c, #(SVCMODE|I_BIT|F_BIT)
	
;------------------------------------------------------------------------------
;Step 1.
;------------------------------------------------------------------------------
;-Enabling the Main Oscillator
;-Normally First instruction in PMC initialisation
;------------------------------------------------------------------------------
;-Main oscillator Enable register	APMC_MOR : Enable main oscillator , OSCOUNT = 0xFF
	ldr     r1, = AT91C_BASE_CKGR	; Get the CKGR Base Address
	ldr 	r0, = AT91C_CKGR_MOSCEN:OR:AT91C_CKGR_OSCOUNT
	str     r0, [r1, #CKGR_MOR]
	
	; set the cpu to SVC32 mode	
;	mrs	r0, cpsr
;	bic	r0, r0, #0x1f
;	orr	r0, r0, #0x13
;	msr	cpsr_cf, r0
		
	; relocate exeception table	 
	adr	r0, ResetEntry
	mov	r1, #0
	mov	r2, #16
copyex
	subs	r2, r2, #1
	ldr	r3, [r0], #4
	str	r3, [r1], #4
	bne	copyex	
	
	IMPORT	LowLevelInit
	
;	ldr	r1, =0x204000;=SVCStack
;	bic	r1, r1, #3				; Insure word alignement
;	mov	sp, r1					; Init stack SYS
	mov	sp, #0x204000
	
	bl 	LowLevelInit
	
	;Initialize stacks
	bl	InitStacks
	
copy_proc_beg
	adr	r0, ResetEntry
	ldr	r2, BaseOfROM
	cmp	r0, r2
	ldreq	r0, TopOfROM
	beq	InitRam	
	ldr r3, TopOfROM
0	
	ldmia	r0!, {r4-r7}
	stmia	r2!, {r4-r7}
	cmp	r2, r3
	bcc	%B0
	
	sub	r2, r2, r3
	sub	r0, r0, r2				
		
InitRam	
	ldr	r2, BaseOfBSS
	ldr	r3, BaseOfZero	
0
	cmp	r2, r3
	ldrcc	r1, [r0], #4
	strcc	r1, [r2], #4
	bcc	%B0	

	mov	r0,	#0
	ldr	r3,	EndOfBSS
1	
	cmp	r2,	r3
	strcc	r0, [r2], #4
	bcc	%B1
	
	IMPORT	irq_handler
  	; Setup IRQ handler
	ldr	r0, =HandleIRQ			;This routine is needed
	;ldr	r1, =IsrIRQ			;if there isn't 'subs pc,lr,#4' at 0x18, 0x1c
	ldr	r1, =irq_handler
	str	r1, [r0]

	IMPORT	main
_main
__main
	EXPORT	_main
	EXPORT	__main
;	swi	0x1234		;test swi
	ldr	r0, =main
	mov	lr, pc
	bx	r0	
	b	.

;===========================================================
;The location of stacks
UserStack	EQU	(_STACK_BASEADDRESS-0x3800)	;0x33ff4800 ~ 
SVCStack	EQU	(_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack	EQU	(_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack	EQU	(_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack	EQU	(_STACK_BASEADDRESS-0x1000)	;0x33ff7000 ~
FIQStack	EQU	(_STACK_BASEADDRESS-0x0)	;0x33ff8000 ~ 

;function initializing stacks
InitStacks
	;Don't use DRAM,such as stmfd,ldmfd......
	;SVCstack is initialized before
	;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
	mrs	r0,cpsr
	bic	r0,r0,#MODEMASK
	orr	r1,r0,#UNDEFMODE|NOINT
	msr	cpsr_cxsf,r1		;UndefMode
	ldr	sp,=UndefStack
	
	orr	r1,r0,#ABORTMODE|NOINT
	msr	cpsr_cxsf,r1		;AbortMode
	ldr	sp,=AbortStack

	orr	r1,r0,#IRQMODE|NOINT
	msr	cpsr_cxsf,r1		;IRQMode
	ldr	sp,=IRQStack
    
	orr	r1,r0,#FIQMODE|NOINT
	msr	cpsr_cxsf,r1		;FIQMode
	ldr	sp,=FIQStack

	bic	r0,r0,#MODEMASK|NOINT
	orr	r1,r0,#SVCMODE
	msr	cpsr_cxsf,r1		;SVCMode
	ldr	sp,=SVCStack
	
	;USER mode has not be initialized.
	
	mov	pc,lr 
	;The LR register won't be valid if the current mode is not SVC mode.

;===========================================================	
	IMPORT  |Image$$RO$$Base|	; Base of ROM code
	IMPORT  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
	IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
	IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
	IMPORT  |Image$$ZI$$Limit|  ; to zero initialise	

BaseOfROM	DCD	|Image$$RO$$Base|
TopOfROM	DCD	|Image$$RO$$Limit|
BaseOfBSS	DCD	|Image$$RW$$Base|
BaseOfZero	DCD	|Image$$ZI$$Base|
EndOfBSS	DCD	|Image$$ZI$$Limit|

		ALIGN
		
	EXPORT DisableInt
DisableInt
	mrs	r0,	cpsr
	orr	r0,	r0, #0xc0
	msr	cpsr_cf, r0
	mov	pc,	lr		

    	AREA RamData, DATA, READWRITE

        ^   _ISR_STARTADDRESS
HandleReset 	#   4
HandleUndef 	#   4
HandleSWI   	#   4
HandlePabort    #   4
HandleDabort    #   4
HandleReserved  #   4
HandleIRQ   	#   4
HandleFIQ   	#   4

;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0   	#   4
HandleEINT1   	#   4
HandleEINT2   	#   4
HandleEINT3   	#   4
HandleEINT4_7	#   4
HandleEINT8_23	#   4
HandleRSV6	#   4
HandleBATFLT   	#   4
HandleTICK   	#   4
HandleWDT	#   4
HandleTIMER0 	#   4
HandleTIMER1 	#   4
HandleTIMER2 	#   4
HandleTIMER3 	#   4
HandleTIMER4 	#   4
HandleUART2  	#   4
HandleLCD 	#   4
HandleDMA0	#   4
HandleDMA1	#   4
HandleDMA2	#   4
HandleDMA3	#   4
HandleMMC	#   4
HandleSPI0	#   4
HandleUART1	#   4
HandleRSV24	#   4
HandleUSBD	#   4
HandleUSBH	#   4
HandleIIC   	#   4
HandleUART0 	#   4
HandleSPI1 	#   4
HandleRTC 	#   4
HandleADC 	#   4

	END
这里先贴出代码,下一篇将对其进行分析。
DG 标签: arm9200start.s
posted @ 2010-05-20 23:12  东 哥  阅读(1386)  评论(0编辑  收藏  举报