【OK6410裸机程序】NAND Flash

这里先转载几篇很详细的博文:

Nand Flash初级了解

Nand Flash基本原理


NAND FLASH(K9GAG08U0D)主的存储器主要有2部分组成:页(Page)、块(Block)。

先初步了解下这块nand芯片:

解释:这张是该芯片结构图,4096个块,1块128页,1页4KB+218B;

片内寻址-5个周期 分列地址和行地址

●    每页大小为:(4K+218)字节,4K用来存储数据,218字节主要用于存储控制信息。如图1.2,每页末尾都有218字节的额外空间,主要是为了便于管理每一页。Eg,使用这218位中的某一位表示该页是否已经写满数据的标志位。如果该位为1,则表示该页写满。反之,表示该页为空。只需要查询该位即可知道该页是否存满数据。

●   每块大小为:128个页

整个NAND FLASH(K9GAG08U0D)由4K(4096)个块组成。

NAND FLASH容量=块的数目*每块的容量

                                =块的数目*(每块包含页的数目*每页的容量)

                  =4KBlocks*(128Pages*(4k+218b))

                  =4KBlocks*128Pages*4k+4KBlocks*128Pages*218b

                  =2048MBytes+109Mbytes


当系统以Nand方式启动时,硬件将Nand Flash的前8KB拷贝到Steppingstone,然后从0地址开始运行程序,在这8KB以内代码中,我们需要完成必要的硬件初始化,如果代码超过8K,我们还需要将剩余代码的搬移到链接地址处,一般在SDRAM/DDR中。其中,硬件部分需要初始化系统时钟、DDR和NAND Flash三部分。

S3C6410启动时拷贝的8K代码不是存储在Nand flash的第一页上,而是存储在Nand flash的前4页上,每页2K,总共8K,这是S3C6410芯片的硬件结构决定的!也就是说,虽然我们的Nand flash的页大小是8K,但是S3C6410为了适应各种型号的Nand flash并保证硬件能正确的拷贝Nand flash中的前8K到SRAM中,硬性的加上这一规定。

从NAND Flash读一页数据到DDR,参数buf为指向DDR的指针,addr是NAND Flash的页号,large_block用来指定页大小。
static int nandll_read_page (unsigned char *buf, unsigned long addr, int large_block)
{
	int i;
	int page_size = 512;

	if (large_block==2)
	    page_size = 4096;

	NAND_ENABLE_CE();  // Ñ¡ÖÐnand

	NFCMMD = NAND_CMD_READ0;

	/* Write Address */
	NFADDR = 0;

	if (large_block)
	    NFADDR = 0;

	NFADDR = (addr) & 0xff;
	NFADDR = (addr >> 8) & 0xff;
	NFADDR = (addr >> 16) & 0xff;

	if (large_block)
	    NFCMMD = NAND_CMD_READSTART;

	NF_TRANSRnB();

	for(i=0; i < page_size; i++) {
	    *buf++ = NFDATA;
	}

	NAND_DISABLE_CE();

	return 0;
}

前8k拷贝到DDR的数据来自NAND Flash的前4页,每页2K。后面的每页4K拷贝。
int copy2ddr(unsigned int nand_start, unsigned int ddr_start, unsigned int len)
{
	unsigned char *dest = (unsigned char *)ddr_start;
	unsigned int free_page = 0;
	int i;

	if(len > 8192)
	{
		free_page = ((len - 8192)+4096) >> 12;
	}
	/* ³õʼ»¯nand flash controller */
	nand_init();
	
	/* ¶Ánand flash */
	/* Read pages */
	for (i = 0; i < 4; i++, dest+=2048){
		nandll_read_page(dest, i, 2);
	}

	/* Read pages */
	for (i = 4; i < (free_page+4); i++, dest+=8192) {
		nandll_read_page(dest, i, 2);
	}
	
	return 0;
}



阅读更多
换一批

没有更多推荐了,返回首页