关于启动代码2440init.s(三)
时间:11-21
来源:互联网
点击:
;=======================================================================
; 哈哈,下面又有看头了,这个初始化程序好像被名曰hzh的高手改过
; 能在NOR NAND 还有内存中运行,当然了,在内存中运行最简单了.
; 在NOR NAND中运行的话都要先把自己拷到内存中.
; 此外,还记得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...吗?
; 这就是拷贝的依据了!!!
;=========================================================================
;BWSCON的[2:1]反映了外部引脚OM[1:0]:若OM[1:0] != 00, 从NOR FLash启动或直接在内存运行;若OM[1:0]==00,则为Nand Flash Mode
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 ; #6 == 0110 --> BWSCON[2:1]
bne copy_proc_beg ;OM[1:0] != 00,NOR FLash boot,不读取NAND FLASH
adr r0, ResetEntry ;否则,OM[1:0] == 0, 为从NAND FLash启动
cmp r0, #0 ;再比较入口是否为0地址处
;如果是0才是真正从NAND 启动,因为其4k被复制到0地址开始的stepingstone 内部sram中
; 注意adr得到的是 相对 地址,非绝对地址 == if use Multi-ice,
bne copy_proc_beg ;如果!=0,说明在using ice, 这种情况也不读取NAND FLASH. dont read nand flash for boot
;nop
;==============这一段代码完成从NAND Flash读代码到RAM=====================
nand_boot_beg ;
mov r5, #NFCONF ;首先设定NAND的一些控制寄存器
;set timing value
ldr r0, =(7<12)|(7<8)|(7<4)
str r0, [r5]
;enable control
ldr r0, =(0<13)|(0<12)|(0<10)|(0<9)|(0<8)|(1<6)|(1<5)|(1<4)|(1<1)|(1<0)
str r0, [r5, #4]
bl ReadNandID ;按着读取NAND的ID号,结果保存在r5里
mov r6, #0 ;r6设初值0.
ldr r0, =0xec73 ;期望的NAND ID号
cmp r5, r0 ;这里进行比较
beq ? ;相等的话就跳到下一个1标号处
ldr r0, =0xec75 ;这是另一个期望值
cmp r5, r0
beq ? ;相等的话就跳到下一个1标号处
mov r6, #1 ;不相等,设置r6=1.
1
bl ReadNandStatus ;读取NAND状态,结果放在r1里
mov r8, #0 ; r8设初值0,意义为页号
ldr r9, =ResetEntry ; r9设初值为初始化程序入口地址
; 注意,在这里使用的是ldr伪指令,而不是上面用的adr伪指令,它加载的是ResetEntry
; 的绝对地址,也就是我们期望的RAM中的地址,在这里,它和|Image$$RO$$Base|一样
; 也就是说,我如我们编译程序时RO base指定的地址在RAM里,而把生成的文件拷到
; NAND里运行,由ldr加载的r9的值还是定位在内存. ???
2
ands r0, r8, #0x1f ;凡r8为0x1f(32)的整数倍-1,eq有效,ne无效
bne ? ;这句的意思是对每个块(32页)进行检错 -- 在每个块的开始页进行
mov r0, r8 ;r8->r0
bl CheckBadBlk ;检查NAND的坏区
cmp r0, #0 ;比较r0和0
addne r8, r8, #32 ;存在坏块的话就跳过这个坏块: + 32得到下一块. 故: r8 = blockpage addr,因为读写是按页进行的(每页512Byte)
bne ? ;然后跳到4进行循环条件判断。没有的话就跳到标号3处copy当前页
3
mov r0, r8 ;当前页号->r0
mov r1, r9 ;当前目标地址->r1
bl ReadNandPage ;读取该页的NAND数据到RAM
add r9, r9, #512 ;每一页的大小是512Bytes
add r8, r8, #1 ;r8指向下一页
4
cmp r8, #256 ;比较是否读完256页即128KBytes
;注意:这说明此程序默认拷贝128KByte的代码(by Tinko)
bcc ? ;如果r8小于256(没读完),就返回前面的标号2处
; now copy completed
mov r5, #NFCONF ;Disable NandFlash
ldr r0, [r5, #4]
bic r0, r0, #1
str r0, [r5, #4]
ldr pc, =copy_proc_beg ;调用copy_proc_beg
;个人认为应该为InitRam ?????????????????????????????
;===========================================================
copy_proc_beg
adrl r0, ResetEntry ;ResetEntry值->r0
;这里应该注意,使用的是adr,而不是ldr。使用ldr说明ResetEntry是个绝对地址,这个地址是在程序链接的时候
;确定的。而使用adr则说明ResetEntry的地址和当前代码的执行位置有关,它是一个相对的地址。比如这段代码
;在stepingstone里面执行,那么ResetEntry的地址就是零。如果在RAM里执行,那么ResetEntry就应是RAM的一个
;地址,应该等于RO base。
ldr r2, BaseOfROM ;BaseOfROM值(后面有定义)->r2
cmp r0, r2 ;比较 ResetEntry 和 BaseOfROM
ldreq r0, TopOfROM ;如果相等的话(在内存运行 --- ice -- 无需复制code区中的ro段,但需要复制code区中的rw段),TopOfROM->r0
beq InitRam ;同时跳到InitRam
;否则,下面开始复制code的RO段
;=========================================================
;下面这个是针对代码在NOR FLASH时的拷贝方法
;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM
;TopOfROM和BaseOfROM为|Image$$RO$$Limit|和|Image$$RO$$Base|
;|Image$$RO$$Limit|和|Image$$RO$$Base|由连接器生成
;为生成的代码的代码段运行时的起启和终止地址
;BaseOfBSS和BaseOfZero为|Image$$RW$$Base|和|Image$$ZI$$Base|
;|Image$$RW$$Base|和|Image$$ZI$$Base|也是由连接器生成
;两者之间就是初始化数据的存放地
; --在加载阶段,不存在ZI区域--
;=======================================================
ldr r3, TopOfROM
0
ldmia r0!, {r4-r7} ;开始时,r0 = ResetEntry --- source
stmia r2!, {r4-r7} ;开始时,r2 = BaseOfROM --- destination
cmp r2, r3 ;终止条件:复制了TopOfROM-BaseOfROM大小
bcc ?
;---------------------------------------------------------------
; 下面2行,根据理解,由tinko添加
; 猜测上面的代码不应该用" ! ",以至于地址被修改。这里重新赋值
;---------------------------------------------------------------
adrl r0, ResetEntry ;dont use adr, cause out of range error occures
ldr r2, BaseOfROM
;旨在计算出正确的RW区起始位置
; 下面2行目的是为了计算正确的r0(必须使之指向code区中的rw域开始处)
sub r2, r2, r3 ;r2=BaseOfROM-TopOfROM=(-)代码长度
sub r0, r0, r2 ;r0=ResetEntry-(-)代码长度=ResetEntry+代码长度
InitRam
;复制代码加载位置中的RM区到|Image$$RW$$Base|
ldr r2, BaseOfBSS ;BaseOfBSS->r2 , BaseOfBSS = |Image$$RW$$Base|
ldr r3, BaseOfZero ;BaseOfZero->r3 , BaseOfZero = |Image$$ZI$$Base|
0
cmp r2, r3 ;比较BaseOfBSS和BaseOfZero
ld
; 哈哈,下面又有看头了,这个初始化程序好像被名曰hzh的高手改过
; 能在NOR NAND 还有内存中运行,当然了,在内存中运行最简单了.
; 在NOR NAND中运行的话都要先把自己拷到内存中.
; 此外,还记得上面提到的|Image$$RO$$Base|,|Image$$RO$$Limit|...吗?
; 这就是拷贝的依据了!!!
;=========================================================================
;BWSCON的[2:1]反映了外部引脚OM[1:0]:若OM[1:0] != 00, 从NOR FLash启动或直接在内存运行;若OM[1:0]==00,则为Nand Flash Mode
; 注意adr得到的是 相对 地址,非绝对地址 == if use Multi-ice,
;nop
;==============这一段代码完成从NAND Flash读代码到RAM=====================
nand_boot_beg
;set timing value
;enable control
1
2
3
4
; now
;===========================================================
copy_proc_beg
;=========================================================
;下面这个是针对代码在NOR FLASH时的拷贝方法
;功能为把从ResetEntry起,TopOfROM-BaseOfROM大小的数据拷到BaseOfROM
;TopOfROM和BaseOfROM为|Image$$RO$$Limit|和|Image$$RO$$Base|
;|Image$$RO$$Limit|和|Image$$RO$$Base|由连接器生成
;为生成的代码的代码段运行时的起启和终止地址
;BaseOfBSS和BaseOfZero为|Image$$RW$$Base|和|Image$$ZI$$Base|
;|Image$$RW$$Base|和|Image$$ZI$$Base|也是由连接器生成
;两者之间就是初始化数据的存放地
; --在加载阶段,不存在ZI区域--
;=======================================================
0
InitRam
0
启动代码244 相关文章:
- ARM启动代码分析(2440init.c)(11-22)
- 关于启动代码2440init.s(一)(11-21)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)