准备分析
资源工具
着手写程序
(1) void board_init_f_nand ((unsigned long bootflag)) ,负责调用copy_uboot_to_ram_nand()和uboot = (void *)0xd0024010;
(2) int copy_uboot_to_ram_nand (void),判断NandFlash类型页的大小。调用int nandll_read_blocks。
(3) int nandll_read_blocks (ulong dst_addr, ulong size, int large_block),读一块大小。
(4) int nandll_read_page (uchar *buf, ulong addr, int large_block),读一页大小,并通过串口打印出NFDATA8_REG寄存器的值。
具体的实现:
void board_init_f_nand(unsigned long bootflag)
{
__attribute__((noreturn)) void (*uboot)(void);
copy_uboot_to_ram_nand();
/* Jump to U-Boot image */
uboot = (void *)0xd0024010;
(*uboot)();
/* Never returns Here */
}
int copy_uboot_to_ram_nand (void)
{
int large_block = 0;
int i;
vu_char id;
NAND_CONTROL_ENABLE();
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READID;
NFADDR_REG = 0x00;
/* wait for a while */
for (i=0; i<200; i++);
id = NFDATA8_REG;
id = NFDATA8_REG;
if (id > 0x80)
large_block = 1;
if(id == 0xd5)
{ //page_size = 8k
large_block = 3;
}
/* read NAND Block.
* 128KB ->240KB because of U-Boot size increase. by scsuh
* So, read 0x3c000 bytes not 0x20000(128KB).
*/
//return nandll_read_blocks(CONFIG_SYS_TEXT_BASE, COPY_BL2_SIZE, large_block);
return nandll_read_blocks(0xd0024000, 0x4000, large_block);
}
/*
* Read data from NAND.
*/
static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
uchar *buf = (uchar *)dst_addr;
int i;
uint page_shift = 9;
if (1 == large_block)
{
page_shift = 11;
/* Read pages */
for (i = (0x6000>>page_shift); i < (size>>page_shift); i++, buf+=(1<<page_shift))
{
nandll_read_page(buf, i, large_block);
}
}
else if(3 == large_block)
{
page_shift = 13;
for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1)))
{
nandll_read_page(buf, i, large_block-1);
}
}
return 0;
}
/*
* address format
* 17 16 9 8 0
* --------------------------------------------
* | block(12bit) | page(5bit) | offset(9bit) |
* --------------------------------------------
*/
static int nandll_read_page (uchar *buf, ulong addr, int large_block)
{
int i;
volatile char c;
int page_size = 512;
if (1 == large_block)
page_size = 2048;
else if (2 == large_block)
page_size = 4096;
else if (3 == large_block)
page_size = 8192;
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READ0;
/* Write Address */
NFADDR_REG = 0;
if (large_block)
NFADDR_REG = 0;
NFADDR_REG = (addr) & 0xff;
NFADDR_REG = (addr >> 8) & 0xff;
NFADDR_REG = (addr >> 16) & 0xff;
if (large_block)
NFCMD_REG = NAND_CMD_READSTART;
NF_TRANSRnB();
/* for compatibility(2460). u32 cannot be used. by scsuh */
for(i=0; i < page_size; i++)
{
c = NFDATA8_REG;
*buf++ = c;
puthex(c);
putc(' ');
}
NAND_DISABLE_CE();
return 0;
}
下载运行
同《
S5PV210的LED应用(一)》
运行调试
对比如图所示:
得到结论,前16k代码在NandFlash存储方式如下:
遗留问题
1.无