2440init代码分析(2)

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

ARM连接器定义了一些符号,这些符号中都包含字符$$ARM连接器生成映像文件时,用它们来代表文件中各域的起始地址以及存储区域界限、各输出段的起始地址以及存储区域界限、各输入段的起始地址以及存储区域的界限。其中

64-65RO输出段运行时起始地址和存储区域界限

66RW输出段运行时起始地址

67-68ZI输出段运行时起始地址和存储区域界限

mini2440中,设置了RO段的起始地址为0x30000000,RW段是紧挨着RO段,ZI段紧挨RW段,下面是我编译的结果

Execution Region ER_RO (Base: 0x30000000, Size: 0x000344b4, Max: 0xffffffff, ABSOLUTE)

Execution Region ER_RW (Base: 0x300344b4, Size: 0x000615e8, Max: 0xffffffff, ABSOLUTE)

Execution Region ER_ZI (Base: 0x30095a9c, Size: 0x0004c7d0, Max: 0xffffffff, ABSOLUTE)

其中RO段的起始地址为0x30000000,大小为0x344B4。而RW的起始地址为0x300344B4=ROBase+RO段的size,同样,ZI=RWBase+RWSize. 

070 	IMPORT	MMU_SetAsyncBusMode
071 	IMPORT	MMU_SetFastBusMode	;
072 
073 	IMPORT  Main    ; The main entry of mon program
074 	IMPORT  CopyProgramFromNand

70-74行分别导入需要的变量和函数,这些变量和函数在其它文件中的定义。

70-71行设置异步总线模式和快速总线模式

73-74行分别为main函数(C语言的入口函数)和拷贝代码到RAM中的函数

076        AREA    Init,CODE,READONLY

76AREA定义本段为代码段,段名为init.段的属性为只读,同时我们在DebugRel_bin Setting ---à>>Linker--à>>ARMLinker---à>>LayOut中看到

说明Init段会先执行。

078 	ENTRY
079 	
080 	EXPORT	__ENTRY
081 __ENTRY

77-81行映像文件运行时的入口点,同时把入口点导出。

082 ResetEntry
083 	;1)The code, which converts to Big-endian, should be in little endian code.
084 	;2)The following little endian code will be compiled in Big-Endian mode.
085 	;  The code byte order should be changed as the memory bus width.
086 	;3)The pseudo instruction,DCD can not be used here because the linker generates error.
087 	ASSERT	:DEF:ENDIAN_CHANGE
088 	[ ENDIAN_CHANGE
089 	    ASSERT  :DEF:ENTRY_BUS_WIDTH
090 	    [ ENTRY_BUS_WIDTH=32
091 		b	ChangeBigEndian	    ;DCD 0xea000007
092 	    ]
093 
094 	    [ ENTRY_BUS_WIDTH=16
095 		andeq	r14,r7,r0,lsl #20   ;DCD 0x0007ea00
096 	    ]
097 
098 	    [ ENTRY_BUS_WIDTH=8
099 		streq	r0,[r0,-r10,ror #1] ;DCD 0x070000ea
100 	    ]
101 	|
102 	    b	ResetHandler
103     ]
104 	b	HandlerUndef	;handler for Undefined mode
105 	b	HandlerSWI	;handler for SWI interrupt
106 	b	HandlerPabort	;handler for PAbort
107 	b	HandlerDabort	;handler for DAbort
108 	b	.		;reserved
109 	b	HandlerIRQ	;handler for IRQ interrupt
110 	b	HandlerFIQ	;handler for FIQ interrupt
111 
112 ;@0x20
113 	b	EnterPWDN	; Must be @0x20.
114 ChangeBigEndian
115 ;@0x24
116 	[ ENTRY_BUS_WIDTH=32
117 	    DCD	0xee110f10	;0xee110f10 => mrc p15,0,r0,c1,c0,0
118 	    DCD	0xe3800080	;0xe3800080 => orr r0,r0,#0x80;  //Big-endian
119 	    DCD	0xee010f10	;0xee010f10 => mcr p15,0,r0,c1,c0,0
120 	]
121 	[ ENTRY_BUS_WIDTH=16
122 	    DCD 0x0f10ee11
123 	    DCD 0x0080e380
124 	    DCD 0x0f10ee01
125 	]
126 	[ ENTRY_BUS_WIDTH=8
127 	    DCD 0x100f11ee
128 	    DCD 0x800080e3
129 	    DCD 0x100f01ee
130     ]
131 	DCD 0xffffffff  ;swinv 0xffffff is similar with NOP and run well in both endian mode.
132 	DCD 0xffffffff
133 	DCD 0xffffffff
134 	DCD 0xffffffff
135 	DCD 0xffffffff
136 	b ResetHandler 
137 	
138 HandlerFIQ      HANDLER HandleFIQ
139 HandlerIRQ      HANDLER HandleIRQ
140 HandlerUndef    HANDLER HandleUndef
141 HandlerSWI      HANDLER HandleSWI
142 HandlerDabort   HANDLER HandleDabort
143 HandlerPabort   HANDLER HandlePabort
144 

88-143行分别介绍了大小端及总线的宽度81632位。及发生异常中断的处理,其处理过程使用了MARCO,前面已经介绍过,其中MARCRO的参数值是_ISR_STARTADDRESS+4,+8….

102行当处理器的复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序执行。常用到有下面几中情况,系统加电时和系统复位时。

104行当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义异常中断。

105行由用户定义的中断指令。可用于用户模式下的程序调用特权操作指令。

106行如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,当该被取的指令执行时,处理器产生指令预取中止异常中断。

107行如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问中止异常中断。

108行当处理器外部中断请求引脚有效,而且CPSR寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。

109行当处理器的外部快速中断请求引脚有效,而且CPSR寄存器的F控制位被清除时,处理器产生外部中断请求异常中断

145 IsrIRQ
146 	sub	sp,sp,#4       ;reserved for PC
147 	stmfd	sp!,{r8-r9}
148 
149 	ldr	r9,=INTOFFSET
150 	ldr	r9,[r9]
151 	ldr	r8,=HandleEINT0
152 	add	r8,r8,r9,lsl #2
153 	ldr	r8,[r8]
154 	str	r8,[sp,#8]
155 	ldmfd	sp!,{r8-r9,pc}
156 
157 

145-155行主要用来建立二级向量表。

146行堆栈SP4,用来存放PC指针的跳转,也就是跳转到对应的中断处理函数。

147R8,R9入栈,保存其中的植。

149行把INTOFFSET中的值放到R9中,其中INTOFFSET寄存器主要用来显示IRQ中那一个中断请求,OFFSET值为0~31.

150行把R9中的数值取出来,放到R9中。

151-154行先把HandleEINT0的地址放到R8中,然后R8+R9*4(这个计算的时地址,因为每个中断向量占用四个字节,所以这里乘以4)放到R8中,取出R8中的值放到R8寄存器,写到SP+8的位置,这个位置就是146行保留的地址。

155行恢复R8,R9的值,PC指向中断服务程序。

158        LTORG

158行声明一个数据缓冲池的开始(不知道怎么用)

159

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值