您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 44b0启动代码详细解析
ARM的裸跑试验差不多了,准备上操作系统,可是上操作系统之前还要先搞定Bootloader,Bootloader的第一部分就是汇编代码,也就是启动代码,其实一开始搞裸跑实验的就已经看过启动代码,看着那一句句都是由汇编语句构成的代码,感觉很难,再加上我是在Bootloader启动好得基础上去跑裸跑代码的,所以当时就没深究,可是这块总是一个空白,而现在学Bootloader的时候再次接触了它,于是下定决心一定要把它完全解析透彻,我用的S3C6410,但是6410这方面的资料很少,再加上以前并没有接触过ARM的汇编,对ARM的汇编指令不怎么了解,所以就准备先将最简单的44b0的启动代码搞定,在44b0的基础上在去解析6410的启动代码,经过了一周的奋战终于将44b0的启动代码解析完毕,在解析代码的过程中,学到了很多知识,首先然我熟悉了ARM的指令,比如LDR、STR、CMP等等,以前看到就晕的汇编在现在看来,变得可爱多了,并且顺带也掌握了ARM的指令编码方式,其实解析完44b0的启动代码后,回想一下,其中最难理解的地方就是中断,次之是代码的搬运,它和加载与运行时地址有关,下面准备开始看6410的启动代码,今天先将44b0的启动代码注释笔记贴出,有兴趣的朋友可以看看,呵呵!!;*******************************************************;*NAME:44BINIT.S*;*Version:10.JAn.2003*;*Description:*;*Cstartupcodes*;*Configurememory,InitializeISR,stacks*;*InitializeC-variables*;*Fillzerosintozero-initializedC-variables*;*******************************************************GET..\inc\option.sGET..\inc\memcfg.s;InterruptControl中断寄存器地址《田凯文》INTPNDEQU0x01e00004INTMODEQU0x01e00008INTMSKEQU0x01e0000cI_ISPREQU0x01e00020I_CMSTEQU0x01e0001c;Watchdogtimer看门狗控制寄存器地址《田凯文》WTCONEQU0x01d30000;ClockController时钟控制寄存器地址《田凯文》PLLCONEQU0x01d80000CLKCONEQU0x01d80004LOCKTIMEEQU0x01d8000c;MemoryController存储器寄存器地址《田凯文》REFRESHEQU0x01c80024BWSCONEQU0x01c80000;Pre-definedconstants处理器预定义常量《田凯文》USERMODEEQU0x10FIQMODEEQU0x11IRQMODEEQU0x12SVCMODEEQU0x13ABORTMODEEQU0x17UNDEFMODEEQU0x1bMODEMASKEQU0x1fNOINTEQU0xc0;IRQ、FIQ中断禁止《田凯文》;用来判断是用16位指令集还是32位指令集《田凯文》GBLLTHUMBCODE[{CONFIG}=16THUMBCODESETL{TRUE}CODE32|THUMBCODESETL{FALSE}][THUMBCODECODE32;forstart-upcodeforThumbmode]MACRO;宏定义开始,P128《田凯文》;这个宏的功能就是先将r0寄存器中的值存入栈中,接着又将中断函数的入口地址《田凯文》;以r0为中转,存入数据栈中,再通过栈还原r0的值,接着将存入栈中的中断函数的入口地址《田凯文》;取出,送给PC,以实现中断函数的跳转《田凯文》;如果是IRQ中断并且是非向量中断,就会跳转到标号IsrIRQ处,然后再跳转到中断二级向量表《田凯文》;如果是向量中断则通过这一步,直接跳转到中断二级向量表《田凯文》;非向量中断跳转流程:bHandlerIRQ-HandlerIRQHANDLERHandleIRQ-IsrIRQ-^_ISR_STARTADDRESS《田凯文》;向量中断跳转流程:VECTOR_BRANCH-$HandlerLabelHANDLER$HandleLabel-^_ISR_STARTADDRESS《田凯文》;向量中断比非向量中断少了一个IsrIRQ《田凯文》$HandlerLabelHANDLER$HandleLabel;宏名为HANDLER,参数为$HandleLabel《田凯文》$HandlerLabel;这里定义了一个标号HandlerLabel,是伪操作《田凯文》subsp,sp,#4;减法指令,sp=sp-4,p66《田凯文》stmfdsp!,{r0};这是一个压栈操作,由于它是事先递减方式,所以sp的值先减4,即将r0寄存器中的数据《田凯文》;存入以sp-4的值为地址的内存单元,并且sp的值更新为sp-4《田凯文》;stmfd是对FD类型数据栈操作的指令,因为是FD类型的数据栈《田凯文》;所以栈的地址是递减的,而SP后面的!号,指的是,是否更新基地址寄存器《田凯文》;如果有!号,指令编码对应的W位置1,基地址寄存器,即sp更新,sp=sp-4《田凯文》;这条指令的目的是为了存储r0寄存器的值,因为后面要用到《田凯文》;现在存储,是为了后面的还原《田凯文》;这条指令没有目标寄存器,只有基址寄存器,所以sp代表的就是地址《田凯文》ldrr0,=$HandleLabel;将标号$HandleLabel的值送给r0,$HandleLabel的值就是存放IsrIRQ的地址,在bResetHandler中已经定义过了《田凯文》ldrr0,[r0];将以r0的值为地址的内存单元中的数据取出,存入r0寄存器中,《田凯文》;这条ldr指令中基址寄存器为r0,即第二个操作数的内存地址为0,p34《田凯文》strr0,[sp,#4];将r0的值放入地址为sp+4的存储单元中,这就是前面sp-4的原因,《田凯文》;它是为了给这一步预留存储空间《田凯文》ldmfdsp!,{r0,pc};这是一个出栈操作,由于它是事后递增方式,即将以sp的值为地址的内存单元中《田凯文》;的值存入r0寄存器中,即还原r0寄存器中值,stmfdsp!,{r0}这条指令,就是为了这一刻《田凯文》;再将以sp+4的值为地址的内存单元中的数据取出,即[r0]里面的值,也就是中断函数的入口地址《田凯文》;送给PC寄存器,并且sp更新为sp+8,即sp=sp+8《田凯文》;这条指令没有目标寄存器,只有基址寄存器,所以sp代表的就是地址《田凯文》MEND;宏定义结束《田凯文》IMPORT|Image$$RO$$Limit|;EndofROMcode(=startofROMdata)IMPORT|Image$$RW$$Base|;BaseofRAMtoinitialiseIMPORT|Image$$ZI$$Base|;BaseandlimitofareaIMPORT|Image$$ZI$$Limit|;tozeroinitialiseIMPORTMain;ThemainentryofmonprogramAREAInit,CODE,READONLY;定义一个名为Init的代码段,属性为READONLY《田凯文》ENTRY;伪操作指定程序的入口点p136《田凯文》bResetHandler;fordebugbHandlerUndef;handlerUndefbHandlerSWI;SWIinterrupthandlerbHandlerPabort;handlerPAbortbHandlerDabort;handlerDAbortb.;handlerReservedbHandlerIRQ;非向量中断跳转到此处《田凯文》bHandlerFIQ;***IMPORTANTNOTE***;IftheH/Wvectoredinterrutpmodeisenabled,Theabovetwoinstructionsshould;bechangedlikebelow,towork-aroundwithH/WbugofS3C44B0Xinterruptcontroller.;bHandlerIRQ-subspc,lr,#4;bHandlerIRQ-subspc,lr,#4VECTOR_BRANCH;这是向量中断的入口地址《田凯文》ldrpc,=HandlerEINT0;mGAH/Winterruptvectortableldrpc,=HandlerEINT1;ldrpc,=HandlerEINT2;ldrpc,=HandlerEINT3;ldrpc,=HandlerEINT4567;ldrpc,=HandlerTICK;mGAb.b.ldrpc,=HandlerZDMA0;mGBldrpc,=HandlerZDMA1;ldrpc,=HandlerBDMA0;ldrpc,=HandlerBDMA1;ldrpc,=HandlerWDT;ldrpc,=HandlerUERR01;mGBb.b.ldrpc,=HandlerTIMER0;mGCldrpc,=HandlerTIMER1;ldrpc,=HandlerTIMER2;ldrpc,=HandlerTIMER3;ldrpc,=HandlerTIMER4;ldrpc,=HandlerTIMER5;mGCb.b.ldrpc,=HandlerURXD0;mGDldrpc,=HandlerURXD1;ldrpc,=HandlerIIC;ldrpc,=HandlerSIO;ldrpc,=HandlerUTXD0;ldrpc,=HandlerUTXD1;mGDb.b.ldrpc,=HandlerRTC;mGKAb.;b.;b.;b.;b.;mGKAb.b.ldrpc,=HandlerADC;mGKBb.;b.;b.;b.;b.;mGKBb.b.;0xe0=EnterPWDNldrpc,=EnterPWDNLTORG;声明一个数据缓冲池的开始P120《田凯文》HandlerFIQHANDLERHandleFIQHandlerIRQHANDLERHandleIRQHandlerUndefHANDLERHandleUndefHandlerSWIHANDLERHandleSWIHandlerDabortHANDLERHandleDabortHandlerPabortHANDLERHandlePabortHandlerADCHANDLERHandleADCHandlerRTCHANDLERHandleRTCHandlerUTXD1HANDLERHandleUTXD1HandlerUTXD0HANDLERHandleUTXD0HandlerSIOHANDLERHandleSIOHandlerIICHANDLERHandleIICHandlerURXD1HANDLERHandleURXD1HandlerURXD0HANDLERHandleURXD0HandlerTIMER5HANDLERHandleTIMER5HandlerTIMER4HANDLERHandleTIMER4HandlerTIMER3HANDLERHandleTIMER3HandlerTIMER2HANDLERHandleTIMER2HandlerTIMER1HANDLERHandleTIMER1HandlerTIMER0HANDLERHandleTIMER0HandlerUERR01HANDLERHandleUERR01HandlerWDTHANDLERHandleWDTHandlerBDMA1HANDLERHandleBDMA1HandlerBDMA0HANDLERHandleBDMA0
本文标题:44b0启动代码详细解析
链接地址:https://www.777doc.com/doc-3271648 .html