设为首页 加入收藏

TOP

ARM启动文件2440init.s分析(三)
2014-11-24 14:39:15 来源: 作者: 【 】 浏览:64
Tags:ARM 启动 文件 2440init.s分析
令,检测是否定义该变量,若未定义,报错


[ENTRY_BUS_WIDTH=32 ;definedin option.inc


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


]


b HandlerUndef ;handler for Undefined mode 0X04


b HandlerSWI ;handlerfor SWI interrupt 0X08


b HandlerPabort ;handler for PAbort,指令预取中止 0X0C


b HandlerDabort ;handler for DAbort,数据中止 0X10


b . ;reserved 保留未用 注意小圆点 0X14


b HandlerIRQ ;handlerfor IRQ interrupt 0X18


b HandlerFIQ ;handlerfor FIQ interrupt 0X1C


;这7个中断,每个中断都有固定的中断入口地址,它们位于代码的最前端,不允许另作他用


;@0x20


b EnterPWDN ;Must be 0x20



;下面是改变大小端的程序,采用直接定义 <机器码> 的方式,为什么这么做就得问三星了


;反正我们程序里这段代码也不会去执行,不用去管它


;每一个汇编指令,都对应着一个二进制机器码,这里没有使用指令,直接用了机器码,含义未知


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


;对存储器控制寄存器操作,指定内存模式为Big-endian


;因为刚开始CPU都是按照32位总线的指令格式运行的,如果采用其他的话,CPU别不了,必须转化


;但当系统初始化好以后,则CPU能自动识别



]


[ENTRY_BUS_WIDTH=16


DCD0x0f10ee11


DCD0x0080e380


DCD0x0f10ee01


;因为采用Big-endian模式,采用16位总线时,物理地址的高位和数据的地位对应


;所以指令的机器码也相应的高低对调



]


[ENTRY_BUS_WIDTH=8


DCD0x100f11ee


DCD0x800080e3


DCD0x100f01ee


]


DCD0xffffffff ;swinv 0xffffff is similarwith NOP and run well in both endian mode.


DCD0xffffffff


DCD0xffffffff


DCD0xffffffff


DCD0xffffffff


bResetHandler ;设置成大端后,再次跳到复位指令处





;本文件底部定义了一个数据区(在文件最后),34个字空间,存放相应中断服务程序的首地址。每个字


;空间都有一个标号,以Handle***命名。


;这是宏实例 在这里Handler***就是通过HANDLER这个宏和Handle***建立联系的.



;详细分析:


; 这是宏示例,也就是宏的调用指令,当编译时编译器会把宏调用指令展开


; 这是向量中断



;展开方式(举例):



;HandlerFIQ HANDLERHandleFIQ



;展开后变成:



;HandlerFIQ ;标号,由 " b HandlerFIQ "指令使用(见上,复位处)


; sub sp,sp,#4 ;留出一个空间,为了存放跳转地址给pc。见:strr0,[sp,#4] ,注意sp值并未改变


;


; stmfd sp!,{r0} ;把r0中的内容入栈,保存起来


;


; ldr r0,=HandleFIQ ;HandleFIQ标号,在本文件最下方定义


;


; ldr r0,[r0] ;把HandleXXX所指向的内容(也就是中断程序的入口地址)放入r0


;


; str r0,[sp,#4] ;把入口地址放入刚才留出的一个空间里


;


; ldmfd sp!,{r0,pc} ;出栈的方式恢复r0原值和为pc设定新值(也就完成了到ISR的转跳)。注:栈中r0内容在低地址


;


; 后边的语句展开方式,同上。编译后,代码都展开放置



HandlerFIQ HANDLERHandleFIQ


HandlerIRQ HANDLERHandleIRQ


HandlerUndef HANDLER HandleUndef


HandlerSWI HANDLERHandleSWI


HandlerDabort HANDLER HandleDabort


HandlerPabort HANDLER Han

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Java迷题:等于,还是不等于? 下一篇jQuery倒数计时按钮—setTimeout

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: