新闻中心

EEPW首页>嵌入式系统>设计应用> TQ2440启动代码分析(一)

TQ2440启动代码分析(一)

作者: 时间:2016-11-26 来源:网络 收藏

;===============================================================

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 not 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

;IMPORT指令类似于C语言的extern关键字,下面这些古怪的变量是由编译器生成的

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,RAM起始地址

IMPORT |Image$$ZI$$Base| ; Base and limit of area初始化的起始地址

IMPORT |Image$$ZI$$Limit| ; to zero initialise初始化的结束地址

;===============================================================

107 ;在这里用IMPORT伪指令(和c语言的extren一样)引入外部变量MMU的快速总线

108 ;模式和异步总线模式两个变量

109 ;===============================================================

IMPORT MMU_SetAsyncBusMode

IMPORT MMU_SetFastBusMode ;

IMPORT Main ; The main entry of mon program

IMPORT RdNF2SDRAM ; Copy Image from Nand Flash to SDRAM

初始化程序中必须指明入口地址,因为处理器复位(仿真时,装载image)后PC 要找到入口开始执行代码,当各种异常或是中断产生的时候也要找到各个异常的入口开始执行代

码。从这里开始就是真正的代码入口了!

AREA Init,CODE,READONLY;声明一个名为Init的代码段,

ENTRY 程序的入口点,(调试用)

;ENTRY只是定义一个普通的入口点,且在程序中可以多处定义,如果要使用它作为整

个映像文件的唯一入口点,还需要设置链接器中的相关选项。

EXPORT __ENTRY

__ENTRY

ResetEntry ;复位后的入口

;1)The code, which converts to Big-endian, should be in little endian code.

;2)The following little endian code will be compiled in Big-Endian mode.

; The code byte order should be changed as the memory bus width.

;3)The pseudo instruction,DCD can not be used here because the linker generates error.

ASSERT :DEF:ENDIAN_CHANGE

[ ENDIAN_CHANGE

ASSERT :DEF:ENTRY_BUS_WIDTH

;如果没有定义ENTRY_BUS_WIDTH就报错

[ ENTRY_BUS_WIDTH=32

b ChangeBigEndian ;DCD 0xea000007

]

[ ENTRY_BUS_WIDTH=16

andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00

]

[ ENTRY_BUS_WIDTH=8

streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea

]

|

b ResetHandler;复位异常,开发板上电或复位时进入0x00

]

中断向量表一般位于启动代码的开始部分,它是用户程序与启动代码之间以及启动代码

的各部分之间联系的纽带。它由一个一个的跳转函数组成,它就象一个普通的散转函数,只

不过散转的过程中有硬件机制参与,当系统发生异常时,ARM 处理器会通过硬件机制强制

将PC 指针指向中断向量表中对应的异常跳转函数存储的地址,然后程序会跳转到相应的中

断服务程序去执行。

b HandlerUndef ;handler for Undefined mode 未定义异常,遇到无法识别的指令时0x04

b HandlerSWI ;handler for SWI interrupt,软中断异常0x08

b HandlerPabort ;handler for PAbort指令预取错误时进入0x0c

b HandlerDabort ;handler for DAbort数据访问不能完成时进入0x10

b . ;reserved, 保留 0x14

b HandlerIRQ ;handler for IRQ interrupt发生IRQ 中断时进入0x18

b HandlerFIQ ;handler for FIQ interrupt发生FIQ 中断时进入0x1c

;@0x20

b EnterPWDN ; Must be @0x20.

158 ;===============================================================

159 ;下面是改变大小端的程序,这里采用直接定义机器码的方式,至说为什么这么做

160 ;就得问三星了反正我们程序里这段代码也不会去执行,不用去管它

161 ;===============================================================

ChangeBigEndian

;@0x24

[ ENTRY_BUS_WIDTH=32

DCD 0xee110f10 ;0xee110f10 => mrc p15,0,r0,c1,c0,0

DCD 0xe3800080 ;0xe3800080 => orr r0,r0,#0x80; //Big-endian

DCD 0xee010f10 ;0xee010f10 => mcr p15,0,r0,c1,c0,0

]

[ ENTRY_BUS_WIDTH=16

DCD 0x0f10ee11

DCD 0x0080e380

DCD 0x0f10ee01

]

[ ENTRY_BUS_WIDTH=8

DCD 0x100f11ee

DCD 0x800080e3

DCD 0x100f01ee

]

DCD 0xffffffff ;swinv 0xffffff is similar with NOP and run well in both endian mode.

DCD 0xffffffff

DCD 0xffffffff

DCD 0xffffffff

DCD 0xffffffff

b ResetHandler

;如第前面所说,这里采用HANDLER宏去建立Hander***和Handle***之间的联系

HandlerFIQ HANDLER HandleFIQ

Ha ndlerIRQ HANDLER HandleIRQ

HandlerUndef HANDLER HandleUndef

HandlerSWI HANDLER HandleSWI

HandlerDabort HANDLER HandleDabort

HandlerPabort HANDLER HandlePabort



关键词:TQ2440启动代

评论


技术专区

关闭