NAND Flash启动的问题Word文档格式.docx
- 文档编号:5673663
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:12
- 大小:19.74KB
NAND Flash启动的问题Word文档格式.docx
《NAND Flash启动的问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《NAND Flash启动的问题Word文档格式.docx(12页珍藏版)》请在冰点文库上搜索。
所以,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<
config.h>
#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=start_addr;
i<
(start_addr+size);
){
/*READ0*/
NFCMD=0;
/*WriteAddress*/
NFADDR=i&
0xff;
NFADDR=(i>
>
9)&
17)&
25)&
wait_idle();
for(j=0;
j<
NAND_SECTOR_SIZE;
j++,i++){
*buf=(NFDATA&
0xff);
buf++;
/*chipDisable*/
NFCONF|=0x800;
/*chipdisable*/
return0;
#viboard/sbc2410x/Makefile+28
COBJS:
=sbc2410x.oflash.o==>
=sbc2410x.oflash.onand_read.o
#vicpu/arm920t/start.S
从NandFlash中把数据拷贝到RAM,是由copy_myself程序段完成
(1)在"
ldrpc,_start_armboot"
之前加入(223行):
#ifdefCONFIG_S3C2410_NAND_BOOT
nop
1:
b1b@infiniteloop
on_the_ram:
#endif
(2)在"
_start_armboot:
.wordstart_armboot"
之后加入:
copy_myself:
movr10,lr
@resetNAND
movr1,#NAND_CTL_BASE
ldrr2,=0xf830@initialvalue
strr2,[r1,#oNFCONF]
ldrr2,[r1,#oNFCONF]
bicr2,r2,#0x800@enablechip
movr2,#0xff@RESETcommand
strbr2,[r1,#oNFCMD]
movr3,#0@wait
1:
addr3,r3,#0x1
cmpr3,#0xa
blt1b
2:
ldrr2,[r1,#oNFSTAT]@waitready
tstr2,#0x1
beq2b
orrr2,r2,#0x800@disablechip
@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
b1b@infiniteloop
ok_nand_read:
ldrr0,STR_OK
@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:
subr0,r0,#4
blPrintHexWord
b1b
done_nand_read:
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博客,转载请标明出处:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NAND Flash启动的问题 Flash 启动 问题