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-65行RO输出段运行时起始地址和存储区域界限
66行RW输出段运行时起始地址
67-68行ZI输出段运行时起始地址和存储区域界限
在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=RO段Base+RO段的size,同样,ZI段=RW段Base+RW段Size.
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
76行AREA定义本段为代码段,段名为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行分别介绍了大小端及总线的宽度8,16,32位。及发生异常中断的处理,其处理过程使用了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行堆栈SP减4,用来存放PC指针的跳转,也就是跳转到对应的中断处理函数。
第147行R8,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