您的位置:首页 > 其它

(二)识别NAND Flash Nor Flash

2015-01-08 10:52 369 查看
检测步骤:在启动的时候,将0x4000003c位置开始的四个字节清零,然后读取0x0000003c位置开始的四个字节。
如果回读的结果为零,说明是Nand boot,否则就是Nor boot

修改start.S

第90 行左右添加一个Flash 启动标志,从Nand 启动时将其设置为0 ,从Nor 启动时将其设置为1

.globl _bss_start

_bss_start:

.word __bss_start

.globl _bss_end

_bss_end:

.word _end

.globl bBootFrmNORFlash  声明一个全局变量

bBootFrmNORFlash:

.word 0           给全局变量赋值0

从第224 行左右开始,添加代码为:
判断当前代码位置,如果在内存,直接跳到stack_setup

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

/***************** CHECK_CODE_POSITION***************************************/

adr r0, _start /* r0 <- current position of code */        获得 _start 的实际运行所在的地址值

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */     获得地址_TEXT_BASE中所存放的数据

cmp r0, r1 /* don't reloc during debug */           比较是否相等

beq stack_setup                                   如果相等就跳到堆栈

/***************** CHECK_CODE_POSITION*************************************/

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

/***************** CHECK_BOOT_FLASH ******************************************/

ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* address of Internal SRAM 0x4000003C*/ 内部SRAM的地址

mov r0, #0 /* r0 = 0 */

str r0, [r1] 写0

mov r1, #0x3c /* address of 0x0000003C*/ 被映射后的地址

ldr r0, [r1]

cmp r0, #0 /* 判断0x0000003C所指向的4个字节是否被清0*/ 比较

bne relocate /* 没有被清0,就是在Nor Flash中启动,则跳到Nor Flash的重定向代码处relocate*/

/* recovery */

ldr r0, =(0xdeadbeef) /* 被清0,就是在Nand Flash中启动*/ 恢复数据

ldr r1, =( (4<<28)|(3<<4)|(3<<2) ) /* 恢复0x4000003C指向的4字节的数据0xdeadbeef*/

str r0, [r1]

/***************** CHECK_BOOT_FLASH ******************************************/

在Nand Flash 中启动的话,那么Nand Flash 搬移代码如下:
定义u-boot在Nand flash中存放的长度为#define LENGTH_UBOOT 0x100000,可以方便修改
u-boot因为裁剪和增添大小的改变而占的长度

/***************** NAND_BOOT *************************************************/

#define LENGTH_UBOOT 0x100000

#define NAND_CTL_BASE 0x4E000000 NFCONF基地址

#ifdef CONFIG_S3C2440

/* Offset */

#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) ) CLE 和 ALE 持续值= HCLK × 3 TWRPH0 持续值= HCLK × ( 7 + 1 )

str r2, [r1, #oNFCONF] TWRPH1 持续值= HCLK × ( 7 + 1 ) 0:支持 256 字或 512 字节/页的 NAND Flash 存储器

ldr r2, [r1, #oNFCONF] 0=256 字/页 0=3 个地址周期 0=8 位总线

ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control 1:初始化 ECC 编码器/译码器

str r2, [r1, #oNFCONT] 0:强制 nFCE 为低(使能片选) 1:NAND Flash 控制器使能

ldr r2, [r1, #oNFCONT]

ldr r2, =(0x6) @ RnB Clear 110 1:检测 RnB 传输 nCE 输出引脚的状态 0:NAND Flash 存储器忙

str r2, [r1, #oNFSTAT]

ldr r2, [r1, #oNFSTAT]

mov r2, #0xff @ RESET command NAND Flash 存储器命令值

strb r2, [r1, #oNFCMD]

mov r3, #0 @ wait

nand1:

add r3, r3, #0x1

cmp r3, #0xa 循环10次

blt nand1 若上cmp结果为小于 跳转到nand1

nand2:

ldr r2, [r1, #oNFSTAT] @ wait ready 无限循环等待,直到检测到NAND Flash变为繁忙状态

tst r2, #0x4 r2和100按位与

beq nand2 按位与的结果与0比较 若结果为0,跳转到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 //为C代码准备堆栈,DW_STACK_START定义在下面

mov fp, #0 @ no previous frame, so fp=0

@ copy U-Boot to RAM

ldr r0, =TEXT_BASE //传递给C代码的第一个参数:u-boot在RAM中的起始地址

mov r1, #0x0 //传递给C代码的第二个参数:Nand Flash的起始地址

mov r2, #LENGTH_UBOOT //传递给C代码的第三个参数:u-boot的长度大小(128k)

bl nand_read_ll //此处调用C代码中读Nand的函数,现在还没有要自己编写实现

tst r0, #0x0 测试r0是否为0

beq ok_nand_read 如果r0=0, 开始测试是否搬移成功

bad_nand_read:

loop2:

b loop2 @ infinite loop 无限死循环

ok_nand_read:

@ verify 检查搬移后的数据,如果前4k完全相同,表示搬移成功

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

/***************** NAND_BOOT *************************************************/

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

/***************** NOR_BOOT *************************************************/

relocate: /* relocate U-Boot to RAM */

/*********** CHECK_FOR_MAGIC_NUMBER***************/

ldr r1, =(0xdeadbeef)

cmp r0, r1

bne loop3

/*********** CHECK_FOR_MAGIC_NUMBER***************/

adr r0, _start /* r0 <- current position of code */

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2 /* r2 <- size of armboot */

add r2, r0, r2 /* r2 <- source end address */

copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0] */

stmia r1!, {r3-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source end addreee [r2] */

ble copy_loop

SetBootFlag:

ldr r0, =bBootFrmNORFlash

mov r1, #1 /*从Nor启动,将标志设置为1*/

str r1, [r0]

/***************** NOR_BOOT *************************************************/

将下面的代码全部删掉:

#ifndef CONFIG_SKIP_RELOCATE_UBOOT 删掉u-boot中nor Flash启动部分

relocate: /* relocate U-Boot to RAM */

adr r0, _start /* r0 <- current position of code */

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */

cmp r0, r1 /* don't reloc during debug */

beq stack_setup

ldr r2, _armboot_start

ldr r3, _bss_start

sub r2, r3, r2 /* r2 <- size of armboot */

add r2, r0, r2 /* r2 <- source end address */

copy_loop:

ldmia r0!, {r3-r10} /* copy from source address [r0] */

stmia r1!, {r3-r10} /* copy to target address [r1] */

cmp r0, r2 /* until source end addreee [r2] */

ble copy_loop

#endif /* CONFIG_SKIP_RELOCATE_UBOOT *

第378 行左右添加代码:

_start_armboot: .word start_armboot

#define STACK_BASE 0x33f00000 定义栈的基地址和大小

#define STACK_SIZE 0x10000

.align 2

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: