微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 自动识别启动模式Nand Or Nor

自动识别启动模式Nand Or Nor

时间:11-22 来源:互联网 点击:

UBOOT-2010-03在S3C2440上的移植<二>------------硬件初始化

http://www.linuxidc.com/Linux/2011-11/46993p2.htm

Notes:2)下面代码段红色部分为删除部分

Notes:3)下面代码段绿色部分为添加部分

4.1)Notes:以下资源来自大神Tekkaman Ninja博客点击查看原文

移植之前还是请大家先看S3C2440数据手册<第五章存储器控制器>中的(也就是那个映射图),从理论上来讲,对于0x40000000以后的内存,只有在Nor boot的时候才存在;而在nand

boot 的时候他被映射到了0x00000000,在0x40000000以后不存在内存。如果我们在启动的时候,将一些特定的数据写入0x40000000~0x40001000之间,那么按照数据手册上的说法,如果回读的结果和写入的一致说明是nor boot,否则就是nand boot!<写这个文章的时候我又看了一次。。。。。。。。。>

从上图我们可以看出,无论是Nor boot还是nandboot ,这4K的内部SRAM都被映射到了0x40000000,而在nandboot的时候,这块内存同时还被映射到了0x00000000。那么一开始提出的办法就不可行了,而且在nandboot 的时候,写入0x40000000~0x40001000还会破坏自身的程序。

但是通过上面的图,我想到了解决的办法:
在启动的时候,用程序将0x40000000~0x40001000中的某些位置清零,如果回读0x00000000~0x00001000中的相应位置后为零,说明是Nand boot,如果是原来的数据(一定要选非零的位置)就是Nor boot。判断完后如果是nand boot,还要恢复被改动的数据,再进入自拷贝阶段。
只要检测的位置合理,这方法是可行的。现在的关键是选什么位置的数据最好呢?经过查看源码,我选择了在start.S文件开头,全局中断向量之后的:

.balignl 16,0xdeadbeef


选这个数据作为检测位置的理由如下:
(1)他是非零数,而且数据是确定的:0xdeadbeef;
(2)他的位置是固定的:0x0000003c(0x4000003c);
(3)他在检测程序之前,不会影响程序的向下运行;
(4)他不属于程序,他是一个程序中的魔数(Magic Number),用魔数来检测也比较合理。

所以我最后的检测步骤是:
在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。如果回读的结果为零,说明是nand boot,否则就是Nor boot(为了保险还可以判断是否为0xdeadbeef,不是的话就说明有未知错误,死循环!)。但是最后有一点很重要:如果是Nand boot,必须要复原清零的数据。原因是:在nand boot过后,会核对内部SRAM中的4K程序,和从Nand中拷贝到SDRAM的前4K程序是否一致,如果不一致会进入死循环。

.globl bBootFrmNORFlash
bBootFrmNORFlash:
.word 0
4.1.2)判断当前代码位置,如果在内存,直接跳到stack_setup


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif

adr r0, _start
ldr r1, _TEXT_BASE
cmp r0, r1
beq stack_setup

4.1.3)如果代码当前位置不在内存中,就判断启动方式为Nand Flash或者Nor Flash

Notes:没有说明就默认在以上代码的后面添加

ldr r1, =( (4<28)|(3<4)|(3<2) )
mov r0, #0
str r0, [r1]

mov r1, #0x3c
ldr r0, [r1]
cmp r0, #0
bne relocate


ldr r0, =(0xdeadbeef)
ldr r1, =( (4<28)|(3<4)|(3<2) )
str r0, [r1]

4.1.4)在Nand Flash中启动的话,那么Nand Flash搬移代码如下:

Notes:定义u-boot在Nand flash中存放的长度为#define LENGTH_UBOOT 0x100000<1M>,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。

#define LENGTH_UBOOT 0x100000
#define NAND_CTL_BASE 0x4E000000

#ifdef CONFIG_S3C2440

#define oNFCONF 0x00
#define oNFCONT 0x04
#define oNFCMD 0x08
#define oNFSTAT 0x20

@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<12)|(7<8)|(7<4)|(0<0) )
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]

ldr r2, =( (1<4)|(0<1)|(1<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]

ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]

mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]

mov r3, #0 @ wait
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1

nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq nand2


ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #oNFCONT]

@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0

@ copy U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #LENGTH_UBOOT
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read

bad_nand_read:
loop2:
b loop2 @ infinite loop
ok_nand_read:
@ verify
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next

notmatch:
loop3:
b loop3 @ infinite loop
#endif

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top