先上张图:
第一步:当S3C2440被配置成从Nand Flash启动时, S3C2440的Nand Flash控制器会在 S3C2440上电时自动把NandFlash上的前4K代码搬移到Boot Internal SRAM,然后系统从起始地址是0x0000_0000的Boot Internal SRAM启动,在这4K代码中我们必须完成CPU的核心配置,把NandFlash上的代码全部拷贝到SDRAM中去,然后跳转到SDRAM中去执行剩余的代码(进入操作系统等等);
第1步:
这一步主要完成的是把NandFlash上的代码拷贝到SDRAM的过程:
(1)先判断是从nor启动还是从nand启动
ldr r0,=BWSCON
ldr r0,[r0]
ands r0,r0, #6 ;OM[1:0] != 0, NOR FLash boot
bne NORRoCopy ;don't read nand flash
adr r0,ResetEntry ;OM[1:0] == 0, NAND FLash boot // ADR 装载参照的地址=subr0,pc,#off_set;
cmp r0,#0 ;if use Multi-ice,//JTAG调试时是直接下载到SDRAM中运行,不需要再从nand拷贝
bne InitRamZero ;don't read nand flash for boot
注意哦,执行adr r0,ResetEntry 后,r0 = PC - off_set,adr得到是相对地址而不是绝对地址。ResetEntry是整个程序的入口处,由链接器指定入口地址,如下图,ResetEntry=RO Base=0x3001_0000即|ImageROBase|。当程序在SDRAM中运行时,当前PC=0x3001_0000+off_set,r0=0x3001_0000,当程序在Boot Internal SRAM运行时,由于程序是从0x0000_0000开始运行的,所以当前PC=0x0000_0000+off_set,即r0=0x0000_0000。所以可以通过 cmp r0,#0来判断程序是否运行在Boot Internal SRAM,如果是,则把NandFlash中的程序拷贝到SDRAM。
(2)从NandFlash拷贝程序到SDRAM
在这步中最让我困惑的是在SDRAM中从哪个地址开始存放从NandFlash拷过来的程序。
;===========================================================
;//将程序从nandflash拷贝到sdram
;===========================================================
nand_boot_beg
bl ClearSdram
mov r5,#NFCONF
;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
mov r6,#0
ldr r0,=0xecF1
cmp r5, r0
beq %F1
; ldr r0,=0xecda
; cmp r5,r0
mov r6,#1 ;Nandaddr(寻址周期 0:4 1:5)
1
bl ReadNandStatus
mov r8,#0
ldr r9,=ResetEntry
mov r10,#32 ;+081010 feiling
上面代码中最关键的是这句:
ldr r9,=ResetEntry
其它都是一些NandFlash的相关设置与操作细节,先不管了。这据代码中用ldr来获得在SDRAM存放代码的起始地址,ldr将ResetEntry的绝对地址
|ImageROBase|赋给了r9。也就是说,从NandFlash拷过来的代码放在了SDRAM中从|ImageR0Base|开始的地址空间里。
第三步:
CPU配置完了,程序和数据也都拷到SDRAM里了,该跳转到SDRAM里去做其他事情了,怎么知道是否跳转到SDRAM呢?这还是地址啊。我之前一直搞不清楚为什么一句ldr pc,=CEntry和bl Main 就能从Boot Internal SRAM直接跳到SDRAM,原来在编译的时候,像ResetEntry和CEntry这些表示地址的标号都被赋于从|ImageROBase|开始之后的地址,只要|ImageROBase|大等于0x3000_0000,利用ldr取得绝对地址后赋给PC就能直接跳转到SDRAM里去了。我之前一直以为ResetEntry=0x0000_0000,而且分不清ldr和adr之间的差别,因此纠结了好久。
ldr pc,=CEntry ;goto compiler address
CEntry
bl Main ;Don t use main()because ......
b .
上一篇:at91rm9200上u-boot移植
下一篇:JZ2440存储管理器代码实现(使用SDRAM)
推荐阅读
史海拾趣
TOP2005 型编程器具有体积小巧,功耗低 ,可靠性高的特点,是专为开发单片机和烧写各类存储器而设计的通用机型。 TOP2005 采用USB通用串口与PC机连接通信,传输速率高,抗干扰性能好,可靠性能极高,而且无需外接电源,特别适合电池供电的笔记本电 ...… 查看全部问答∨ |
我手里有一个atmel 410 24c02n 请问这种型号 和普通的 24c02 有什么区别吗?? 另外,我把写进的数据 读出后, 都是255。这能是什么问题那?? 硬件脚 应该没有问题, scl sda 加了 4.7k 上拉电阻。wp a0 a1 a2 没接。5v电源。 写 ...… 查看全部问答∨ |
现在看设计的产品,无论是手机还是车载DVD还有导航等。都是注重了产品设计。强调了外观、功能、接口等。这样的产品设计是电脑、手机等消费电子的设计观念。用在车载产品上是不合适的。一个车的使用平均无故障时间是2年左右。现在用设计手机的概念去 ...… 查看全部问答∨ |
序 六个星期的培训班学习仿佛在一瞬间就结束了,个中情景仍然历历在目。这六个星期也正是本人遭遇人生道路上的低谷时期,如今生活开始慢慢走上正常的轨道,趁这次总结的机会,回顾一下这 ...… 查看全部问答∨ |
假定从8位AD中读取数据(如果是更高位的AD可定义数据类型为int),子程序为get_ad(); 1、限副滤波 /* A值可根据实际情况调整 value为有效值,new_value为当前采样值 滤波程序返回有效的实际值 &nb ...… 查看全部问答∨ |
|
OEMIoControl: Unsupported Code 0x1010024 - device 0x0101 func 9 网上下载了一个smdk2440的bsp,创建了一个工程,然后build-sysgen,没有错误,有一些warning。生成了nk.nb0文件,将此文件通过usb下载到目标板上运行,串口回传以下信息: Windows CE Kernel for ARM (Thumb Enabled) Built on Jun 24 2004 at 18: ...… 查看全部问答∨ |
我现在要做一块PCB板 ,其中一块集成原件的datasheet中给的引脚尺寸是 例如: 7mm-7.5mm 我画PCB时究竟是选最大值还是最小值 还是取中间一个值呢? 请有设计经验的大侠指教!! 谢谢!… 查看全部问答∨ |
要用verilog HDL 写一个简单的数字分频器,请各位大虾给下代码参考 测试频率为10HZ~9999.9HZ 误差在0.05HZ之内 输入口: 测试信号:clkx 标准时钟信号:clk, … 查看全部问答∨ |
为了能够对CAN中断做出处理,则必须为CAN安装一个中断处理程序 通过使用CANIntStatus()函数,处理程序就能确定是由哪一个条件而引起的中断。 unsigned long CANIntStatus (unsigned long ulBase, tCANIntStsReg eIntStsReg) 每个报文可配置为两 ...… 查看全部问答∨ |