NAND Flash启动的问题.docx

上传人:b****1 文档编号:3029855 上传时间:2023-05-05 格式:DOCX 页数:12 大小:19.74KB
下载 相关 举报
NAND Flash启动的问题.docx_第1页
第1页 / 共12页
NAND Flash启动的问题.docx_第2页
第2页 / 共12页
NAND Flash启动的问题.docx_第3页
第3页 / 共12页
NAND Flash启动的问题.docx_第4页
第4页 / 共12页
NAND Flash启动的问题.docx_第5页
第5页 / 共12页
NAND Flash启动的问题.docx_第6页
第6页 / 共12页
NAND Flash启动的问题.docx_第7页
第7页 / 共12页
NAND Flash启动的问题.docx_第8页
第8页 / 共12页
NAND Flash启动的问题.docx_第9页
第9页 / 共12页
NAND Flash启动的问题.docx_第10页
第10页 / 共12页
NAND Flash启动的问题.docx_第11页
第11页 / 共12页
NAND Flash启动的问题.docx_第12页
第12页 / 共12页
亲,该文档总共12页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

NAND Flash启动的问题.docx

《NAND Flash启动的问题.docx》由会员分享,可在线阅读,更多相关《NAND Flash启动的问题.docx(12页珍藏版)》请在冰点文库上搜索。

NAND Flash启动的问题.docx

NANDFlash启动的问题

从NandFlash启动U-BOOT的基本原理

-------------------------------------------

前4K的问题

如果S3C2410被配置成从NandFlash启动(配置由硬件工程师在电路板设置),S3C2410的NandFlash控制器有一个特殊的功能,在S3C2410上电后,NandFlash控制器会自动的把NandFlash上的前4K数据搬移到4K内部SRAM中,并把0x00000000设置内部SRAM的起始地址,CPU从内部SRAM的0x00000000位置开始启动。

这个过程不需要程序干涉。

程序员需要完成的工作,是把最核心的启动程序放在NandFlash的前4K中。

启动程序的安排

由于NandFlash控制器从NandFlash中搬移到内部SRAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2410的核心配置以及把启动代码(U-BOOT)剩余部分搬到SDRAM中运行。

u-boot源码不支持从nandflash启动,可是s3c2410支持从nandflash启动,开发板(sbc-2410x)加电后s3c2410将nandflash的前4k(保存有u-boot的部分功能--拷贝功能--把nandflash中的内容拷贝到SDRAM)拷贝到sram(s3c2410芯片内的sram)。

这就需要修改u-boot源码,增加u-boot的功能:

使u-boot在得到执行权后能够将其自身拷贝到开发板上SDRAM中,以便处理器能够执行u-boot。

*NORFLASH地址线和数据线分开,来了地址和控制信号,数据就出来。

*NANDFlash地址线和数据线在一起,需要用程序来控制,才能出数据。

通俗的说,就是光给地址不行,要先命令,再给地址,才能读到NAND的数据。

而且都是在一个总线完成的。

NandFlash的命令、地址、数据都通过I/O口发送,管脚复用,这样做做的好处是,可以明显减少NANDFLASH的管脚数目,将来如果设计者想将NANDFLASH更换为更高密度、更大容量的,也不必改动电路板。

NANDFLASH不能够执行程序,本人总结其原因如下:

1.NANDFLASH本身是连接到了控制器上而不是系统总线上。

CPU启动后是要取指令执行的,如果是SROM、NORFLASH等之类的,CPU发个地址就可以取得指令并执行,NANDFLASH不行,因为NANDFLASH是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。

2.NANDFLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。

U-BOOT支持ARM、PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系统,主要用来开发嵌入式系统初始化代码bootloader。

bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的过渡,为运行操作系统提供基本的运行环境,如初始化CPU、堆栈、初始化存储器系统等,其功能类似于PC机的BIOS.

NAND闪存工作原理

S3C2410开发板的NAND闪存由NAND闪存控制器(集成在S3C2410CPU中)和NAND闪存芯片(K9F1208U0A)两大部分组成。

当要访问NAND闪存芯片中的数据时,必须通过NAND闪存控制器发送命令才能完成。

所以,NAND闪存相当于S3C2410的一个外设,而不位于它的内存地址区。

NAND闪存(K9F1208U0A)的数据存储结构分层为:

1设备(Device)=4096块(Block);1块=32页/行(Page/row);1页=528B=数据块(512B)+OOB块(16B)

在每一页中,最后16个字节(又称OOB)在NAND闪存命令执行完毕后设置状态,剩余512个字节又分为前半部分和后半部分。

可以通过NAND闪存命令00h/01h/50h分别对前半部、后半部、OOB进行定位,通过NAND闪存内置的指针指向各自的首地址。

NAND闪存的操作特点为:

擦除操作的最小单位是块;NAND闪存芯片每一位只能从1变为0,而不能从0变为1,所以在对其进行写入操作之前一定要将相应块擦除;OOB部分的第6字节为坏快标志,即如果不是坏块该值为FF,否则为坏块;除OOB第6字节外,通常用OOB的前3个字节存放NAND闪存的硬件ECC(校验寄存器)码;

从NAND闪存启动U-BOOT的设计思路

如果S3C2410被配置成从NAND闪存启动,上电后,S3C2410的NAND闪存控制器会自动把NAND闪存中的前4K数据搬移到内部RAM中,并把0x00000000设置为内部RAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。

因此要把最核心的启动程序放在NAND闪存的前4K中。

由于NAND闪存控制器从NAND闪存中搬移到内部RAM的代码是有限的,所以,在启动代码的前4K里,必须完成S3C2410的核心配置,并把启动代码的剩余部分搬到RAM中运行。

在U-BOOT中,前4K完成的主要工作就是U-BOOT启动的第一个阶段(stage1)。

根据U-BOOT的执行流程图,可知要实现从NAND闪存中启动U-BOOT,首先需要初始化NAND闪存,并从NAND闪存中把U-BOOT搬移到RAM中,最后需要让U-BOOT支持NAND闪存的命令操作。

##################################################################################

对u-boot启动代码start.s(汇编部分)的注解。

需要注意的是代码的搬运过程。

对于从nandflash启动的s3c2410,上电后会自动从nandflash搬移4k代码(肯定包含start.s部分)到0地址的缓存(bootstone)中,然后从0地址开始读取指令并运行。

那么这4k的代码必须实现必要的初始化和u-boot代码的搬移(到sdram中),最后u-boot将在sdram中运行。

u-boot默认是从norflash或sdram中启动运行的。

原版的start.s对于代码搬移的实现如下:

1,首先读取_start的地址值(相对pc的值,特别注意adr伪指令)和_TEXT_BASE地址处TEXT_BASE的值(在连接脚本中定义的常数),以判别程序从哪里运行,是否需要搬移。

relocate:

/*relocateU-BoottoRAM*/

adrr0,_start/*r0<-currentpositionofcode*/

ldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/

cmpr0,r1

beqstack_setup

2,如果需要,搬移所有整个代码段到sdram(TEXT_BASE地址处)。

下面用于计算代码段长度和代码段终止地址。

ldrr2,_armboot_start

ldrr3,_bss_start

subr2,r3,r2/*r2<-sizeofarmboot*/

addr2,r0,r2/*r2<-sourceendaddress*/

3,如果是从nandflash启动,上述实际上只有效搬移了4k的代码到sdram,因为u-boot代码段大部分还在nandflash中。

所以需要添加从nandflash拷贝到sdram的代码。

这里由copy_myself函数实现,再次搬移了128k,并且覆盖了前次搬移的4k。

blcopy_myself

4,搬移完成后,程序必须跳到sdram中去运行。

注意下面的ldr伪指令,得到on_the_ram的绝对地址(连接完成后就是个常数值,位于sdram中),然后赋值给pc。

@jumptoram

ldrr1,=on_the_ram

addpc,r1,#0

5,跳到start_armboot(),运行第一跳c指令。

这里的ldr是普通指令,_start_armboot标号处存储了start_armboot()函数的绝对地址(连接完就是个常数)。

到此start.s的工作完成。

on_the_ram:

#endif

/*endadd*/

ldrpc,_start_armboot

_start_armboot:

.wordstart_armboot

##################################################################################

#cdu-boot-1.1.6

在board/bks2410加入NANDFlash读函数,建立nand_read.c,加入如下内容(copyfromvivi):

#viboard/sbc2410x/nand_read.c

-----------------------------------------------

#include

#define__REGb(x)(*(volatileunsignedchar*)(x))

#define__REGi(x)(*(volatileunsignedint*)(x))

#defineNF_BASE0x4e000000

#defineNFCONF__REGi(NF_BASE+0x0)

#defineNFCMD__REGb(NF_BASE+0x4)

#defineNFADDR__REGb(NF_BASE+0x8)

#defineNFDATA__REGb(NF_BASE+0xc)

#defineNFSTAT__REGb(NF_BASE+0x10)

#defineBUSY1

inlinevoidwait_idle(void){

inti;

while(!

(NFSTAT&BUSY))

for(i=0;i<10;i++);

}

#defineNAND_SECTOR_SIZE512

#defineNAND_BLOCK_MASK(NAND_SECTOR_SIZE-1)

/*lowlevelnandreadfunction*/

intnand_read_ll(unsignedchar*buf,

unsignedlongstart_addr,

intsize)

{

inti,j;

if((start_addr&NAND_BLOCK_MASK)||(size&NAND_BLOCK_MASK)){

return-1;/*invalidalignment*/

}

/*chipEnable*/

NFCONF&=~0x800;

for(i=0;i<10;i++);

for(i=start_addr;i<(start_addr+size);){

/*READ0*/

NFCMD=0;

/*WriteAddress*/

NFADDR=i&0xff;

NFADDR=(i>>9)&0xff;

NFADDR=(i>>17)&0xff;

NFADDR=(i>>25)&0xff;

wait_idle();

for(j=0;j

*buf=(NFDATA&0xff);

buf++;

}

}

/*chipDisable*/

NFCONF|=0x800;/*chipdisable*/

return0;

}

#viboard/sbc2410x/Makefile+28

-----------------------------------------------

COBJS:

=sbc2410x.oflash.o==>

COBJS:

=sbc2410x.oflash.onand_read.o

#vicpu/arm920t/start.S

-----------------------------------------------

从NandFlash中把数据拷贝到RAM,是由copy_myself程序段完成

(1)在"ldrpc,_start_armboot"之前加入(223行):

#ifdefCONFIG_S3C2410_NAND_BOOT

blcopy_myself

@jumptoram

ldrr1,=on_the_ram

addpc,r1,#0

nop

nop

1:

b1b@infiniteloop

on_the_ram:

#endif

(2)在"_start_armboot:

.wordstart_armboot"之后加入:

#ifdefCONFIG_S3C2410_NAND_BOOT

copy_myself:

movr10,lr

@resetNAND

movr1,#NAND_CTL_BASE

ldrr2,=0xf830@initialvalue

strr2,[r1,#oNFCONF]

ldrr2,[r1,#oNFCONF]

bicr2,r2,#0x800@enablechip

strr2,[r1,#oNFCONF]

movr2,#0xff@RESETcommand

strbr2,[r1,#oNFCMD]

movr3,#0@wait

1:

addr3,r3,#0x1

cmpr3,#0xa

blt1b

2:

ldrr2,[r1,#oNFSTAT]@waitready

tstr2,#0x1

beq2b

ldrr2,[r1,#oNFCONF]

orrr2,r2,#0x800@disablechip

strr2,[r1,#oNFCONF]

@getreadtocallCfunctions(fornand_read())

ldrsp,DW_STACK_START@setupstackpointer

movfp,#0@nopreviousframe,sofp=0

@copyvivitoRAM

ldrr0,=UBOOT_RAM_BASE

movr1,#0x0

movr2,#0x20000

blnand_read_ll

tstr0,#0x0

beqok_nand_read

#ifdefCONFIG_DEBUG_LL

bad_nand_read:

ldrr0,STR_FAIL

ldrr1,SerBase

blPrintWord

1:

b1b@infiniteloop

#endif

ok_nand_read:

#ifdefCONFIG_DEBUG_LL

ldrr0,STR_OK

ldrr1,SerBase

blPrintWord

#endif

@verify

movr0,#0

ldrr1,=UBOOT_RAM_BASE

movr2,#0x400@4bytes*1024=4K-bytes

go_next:

ldrr3,[r0],#4

ldrr4,[r1],#4

teqr3,r4

bnenotmatch

subsr2,r2,#4

beqdone_nand_read

bnego_next

notmatch:

#ifdefCONFIG_DEBUG_LL

subr0,r0,#4

ldrr1,SerBase

blPrintHexWord

ldrr0,STR_FAIL

ldrr1,SerBase

blPrintWord

#endif

1:

b1b

done_nand_read:

#ifdefCONFIG_DEBUG_LL

ldrr0,STR_OK

ldrr1,SerBase

blPrintWord

#endif

movpc,r10

@clearmemory

@r0:

startaddress

@r1:

length

mem_clear:

movr2,#0

movr3,r2

movr4,r2

movr5,r2

movr6,r2

movr7,r2

movr8,r2

movr9,r2

clear_loop:

stmiar0!

{r2-r9}

subsr1,r1,#(8*4)

bneclear_loop

movpc,lr

#endif@CONFIG_S3C2410_NAND_BOOT

(3)在文件的最后加入:

.align2

DW_STACK_START:

.wordSTACK_BASE+STACK_SIZE-4

#viinclude/configs/sbc2410x.h

-----------------------------------------------

(1)将CONFIG_SERVERIP设置为主机IP

这样以后在通过网络下载内核映像时,就不用就该IP地址了。

(这一项修改与nandflash没有关系)

#defineCONFIG_SERVERIP192.168.0.240

(2)在文件末尾添加如下内容

/*

*NandflashBoot

*/

#defineCONFIG_S3C2410_NAND_BOOT1

#defineSTACK_BASE0x33f00000

#defineSTACK_SIZE0x8000

#defineUBOOT_RAM_BASE0x33f80000

/*NANDFlashController*/

#defineNAND_CTL_BASE0x4E000000

#definebINT_CTL(Nb)__REG(INT_CTL_BASE+(Nb))

/*Offset*/

#defineoNFCONF0x00

#defineoNFCMD0x04

#defineoNFADDR0x08

#defineoNFDATA0x0c

#defineoNFSTAT0x10

#defineoNFECC0x14

本文来自CSDN博客,转载请标明出处:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2