S3C2440启动代码分析
时间:11-21
来源:互联网
点击:
- !=00,NORFLashboot,不读取NANDFLASH
- adrr0,ResetEntry;否则,OM[1:0]==0,为从NANDFLash启动
- cmpr0,#0;再比较入口是否为0地址处
- ;如果是0才是真正从NAND启动,因为其4k被复制到0地址开始的stepingstone内部sram中
- ;注意adr得到的是相对地址,非绝对地址==ifuseMulti-ice,
- bnecopy_proc_beg;如果!=0,说明在usingice,这种情况也不读取NANDFLASH.dontreadnandflashforboot
- ;nop
- ;==============这一段代码完成从NANDFlash读代码到RAM=====================
- nand_boot_beg;
- movr5,#NFCONF;首先设定NAND的一些控制寄存器
- ;settimingvalue
- ldrr0,=(7<12)|(7<8)|(7<4)
- strr0,[r5]
- ;enablecontrol
- ldrr0,=(0<13)|(0<12)|(0<10)|(0<9)|(0<8)|(1<6)|(1<5)|(1<4)|(1<1)|(1<0)
- strr0,[r5,#4]
- blReadNandID;按着读取NAND的ID号,结果保存在r5里
- movr6,#0;r6设初值0.
- ldrr0,=0xec73;期望的NANDID号
- cmpr5,r0;这里进行比较
- beq%F1;相等的话就跳到下一个1标号处
- ldrr0,=0xec75;这是另一个期望值
- cmpr5,r0
- beq%F1;相等的话就跳到下一个1标号处
- movr6,#1;不相等,设置r6=1.
- 1
- blReadNandStatus;读取NAND状态,结果放在r1里
- movr8,#0;r8设初值0,意义为页号
- ldrr9,=ResetEntry;r9设初值为初始化程序入口地址
- ;注意,在这里使用的是ldr伪指令,而不是上面用的adr伪指令,它加载的是ResetEntry
- ;的绝对地址,也就是我们期望的RAM中的地址,在这里,它和|Image
Base|一样RO - ;也就是说,我如我们编译程序时RObase指定的地址在RAM里,而把生成的文件拷到
- ;NAND里运行,由ldr加载的r9的值还是定位在内存.???
- 2
- andsr0,r8,#0x1f;凡r8为0x1f(32)的整数倍-1,eq有效,ne无效
- bne%F3;这句的意思是对每个块(32页)进行检错--在每个块的开始页进行
- movr0,r8;r8->r0
- blCheckBadBlk;检查NAND的坏区
- cmpr0,#0;比较r0和0
- addner8,r8,#32;存在坏块的话就跳过这个坏块:+32得到下一块.故:r8=blockpageaddr,因为读写是按页进行的(每页512Byte)
- bne%F4;然后跳到4进行循环条件判断。没有的话就跳到标号3处copy当前页
- 3
- movr0,r8;当前页号->r0
- movr1,r9;当前目标地址->r1
- blReadNandPage;读取该页的NAND数据到RAM
- addr9,r9,#512;每一页的大小是512Bytes
- addr8,r8,#1;r8指向下一页
- 4
- cmpr8,#256;比较是否读完256页即128KBytes
- ;注意:这说明此程序默认拷贝128KByte的代码(byTinko)
- bcc%B2;如果r8小于256(没读完),就返回前面的标号2处
- ;nowcopycompleted
- movr5,#NFCONF;DisableNandFlash
- ldrr0,[r5,#4]
- bicr0,r0,#1
- strr0,[r5,#4]
- ldrpc,=copy_proc_beg;调用copy_proc_beg
- ;个人认为应该为InitRam?????????????????????????????
- ;===========================================================
- copy_proc_beg
- adrlr0,ResetEntry;ResetEntry值->r0
- ;这里应该注意,使用的是adr,而不是ldr。使用ldr说明ResetEntry是个绝对地址,这个地址是在程序链接的时候
- ;确定的。而使用adr则说明ResetEntry的地址和当前代码的执行位置有关,它是一个相对的地址。比如这段代码
- ;在stepingstone里面执行,那么ResetEntry的地址就是零。如果在RAM里执行,那么ResetEntry就应是RAM的一个
- ;地址,应该等于RObase。
- ldrr2,BaseOfROM;BaseOfROM值(后面有定义)->r2
- cmpr0,r2;比较ResetEntry和BaseOfROM
- ldreqr0,TopOfROM;如果相等的话(在内存运行---ice--无需复制code区中的ro段,但需要复制code区中的rw段),TopOfROM->r0
- beqInitRam;同时跳到InitRam
- ;否则,下面开始复制code的RO段
- ;=========================================================
- ;下面这个是针对代码在NORFLASH时的拷贝方法
- ;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM
- ;TopOfROM和BaseOfROM为|Image
Limit|和|ImageRO
Base|RO - ;|Image
Limit|和|ImageRO
Base|由连接器生成RO - ;为生成的代码的代码段运行时的起启和终止地址
- ;BaseOfBSS和BaseOfZero为|Image
Base|和|ImageRW
Base|ZI - ;|Image
Base|和|ImageRW
Base|也是由连接器生成ZI - ;两者之间就是初始化数据的存放地
- ;--在加载阶段,不存在ZI区域--
- ;=======================================================
- ldrr3,TopOfROM
- 0
- ldmiar0!,{r4-r7};开始时,r0=ResetEntry---source
- stmiar2!,{r4-r7};开始时,r2=BaseOfROM---destination
- cmpr2,r3;终止条件:复制了TopOfROM-BaseOfROM大小
- bcc%B0
- ;---------------------------------------------------------------
- ;下面2行,根据理解,由tinko添加
- ;猜测上面的代码不应该用"!",以至于地址被修改。这里重新赋值
- ;---------------------------------------------------------------
- adrlr0,ResetEntry;dontuseadr,causeoutofrangeerroroccures
- ldrr2
S3C2440启动代 相关文章:
- 深入分析S3C2440启动代码中大小端问题(11-22)
- S3C2440启动代码中应用程序执行环境的初始化(11-22)
- S3C2440启动代码 中断分析(11-22)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)