三星uboot1.1.6源码分析——start.s(3)---从NAND复制uboot到外部RAM(2)
想要看懂这部分代码,需要先看下面这 nandll_read_page源码的分析,这个源码的作用,就是根据我们给定的地址,从具体的page中读出数据。但是这里为什么要用两个循环呢?不太懂。
-----------------------------------------------------------
现在有遇到了一个函数, nandll_read_page,同样它的源码也在同一个文件中,如下所示:
/*
* 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;
int page_size = 512;
if (large_block==1)
page_size = 2048;
if (large_block==2) 这个上面说过了
page_size = 4096;
NAND_ENABLE_CE(); 这个上面也说过了
NFCMD_REG = NAND_CMD_READ0;
-----------------------------------
#define NAND_CMD_READ00
----------------------------------------------------------------
/* 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; ------------看下面的图:
------------------------------------------------------------
这里涉及到地址转化,和地址发送的顺序问题,下面这个图是地址发送的顺序,那么地址怎样转化的呢?
这里的addr是上面参数传递进来的。
--------------------------------------------------------------------
if (large_block)
NFCMD_REG = NAND_CMD_READSTART;
---------------------------------------
其中有:
#define NAND_CMD_READSTART0x30
看上面那个图,就应该知道为什么了。
---------------------------------------
NF_TRANSRnB();----------------检测忙标志,有如下定义:
-----------------------------------------------------
#define NF_TRANSRnB()do { while(!(NFSTAT_REG & (1 << 0))); } while(0)
---------------------------------------
/* for compatibility(2460). u32 cannot be used. by scsuh */ ------把数据读到buf中。
for(i=0; i < page_size; i++) {
*buf++ = NFDATA8_REG;
}
NAND_DISABLE_CE(); 禁止NAND
return 0;
}
----------------------------------------------------------------
else 这个我们用不到,分析方法和上面一样 这里就只用了一个循环。
{
for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
nandll_read_page(buf, i, large_block);
}
}
return 0;
}