uboot copy_from_nand代码详解

来源:互联网 发布:vb九九乘法表 编辑:程序博客网 时间:2024/06/11 21:11

uboot copy_from_nand代码详解

copy_from_nand函数简介:

       函数将会把nand flash中的uboot二进制程序镜像拷贝到内存中,通常这一步出现问题,uboot是不可能引导起来的,串口也不会有信息吐出(当然啦,因为uboot不在内存,如何执行啊

 

代码分析:

       1.先贴函数代码,在后面再分析,copy_from_nand函数的代码我们可以在cpu/s3c64xx/start.S的278行看到,上图:

图(1)

273~277行:解释很给力,273行告诉你了这个函数的功能就是把nand flash中存放的uboot镜像文件拷贝到内存中,然后再到内存中去执行uboot,这样我们的uboot就可以在内存中运行起来了。274行告诉我们r0是会被比较的大小。293行把0x0c000000里面的值赋给r0了,我们要比较拷贝到内存的uboot和steppingstone里面是否一样啊?所以我们要比较一下咯(295和297行)

288行:copy_uboot_to_ram这个函数是在C语言里面写的,C语言的程序在编译器编译的时候肯定会有出入栈的操作,会用到sp指针,所以我们在进入这个函数之前是必须设置sp的,所以288行前的不解释了。我们直接进入这个copy_uboot_to_ram函数吧:

图(2)

这个函数的实现在cpu/s3c64xx/nand_cp.c的133行,注意的是这个函数必须在整个uboot.bin文件的前4KB,所以我们看到u-boot.lds中会把nand_cp.o链接到uboot二进制文件靠前的位置

139~148行:主要想做的事情就是判断我们的nand flash是大页得还是小页的,现在主流的的nand flash有512页和2048页两种,在后续的代码操作中有区别,所以在进行nand操作前,必须先判断出是大页还是小页。139行是在使能芯片,代码是(NFCONT_REG &= ~(1 << 1)),即会把0x70200004这个地址的[1]位清零,那么为什么清零[1]位就能够使能nand flash芯片了呢,我们看下s3c6410 datasheet才能够明白:

图(3)

我们看到图3中的[1]位为0的含义是让Xm0CSn2变成低电平,因为我们的nand flash是接在SRAM2上的,

当Xm0CSn2为低电平时,将能访问我们的nand flash芯片了。

140行:在给nand_flash发送命令,发送的值为0x90,含义是读取芯片的ID等厂商信息,话说对nand flash的控制都是这个套路,因为这就是硬件协议,先使能芯片->发送命令->发送地址序列->读或写数据寄存器->判断准备就绪状态->禁止芯片,这是对nand flash操作的大体过程,根据发送命令的不同还有些区别。我们这次发送的是0x90,代表读取ID信息。发送命令的含义通过读取你nand flash datasheet来查看,你需要看你的nand flash芯片是哪个厂家生产的,下载它的datasheet,如下图:


图(4)

你会发现图(2)在发送命令后,会读两次寄存器。这是因为我们发送完0x90,nand flash会返回5次(好像)值给我们,我们需要的值是第二次返回的值,接着148行判断是否id大于0x80,大于的话就是大页2048字节的。我的芯片是K9F84G08U0B,是大页的,所以这个读出来的值是大于0x80的;

155行:拷贝功能主函数,CFG_PHY_UBOOT_BASE第一个代表要拷贝到内存的地址(0x57e00000),第二个参数0x3c000代表要从nand flash中拷贝的大小,我们进入这个函数:

图(5)

图(5)直接看126行,这个循环会执行0x3c000>>page_shift次,如果是9代表除以512,如果是11代表除以2048,这下明白这个for循环的意思了吧,nand flash硬件一次会读取一个页的大小给我们,那么我们就进入127行的读一页吧,注意会读到buf中,buf可就是我们指定的0x57e00000哦:

图(6)

图6函数会读一页的数据到buf中,即内存中。然后一直读0x3c000/512(2048)次,看你是大页还是小页nand,我的是大页。

图6的85行使能芯片,前面已经说过,87行发送读命令,是0x0,你可以查看图(4),发送读之后,我们就要开始向地址寄存器中写一些地址,告诉nand flash我们要从什么地方开始读数据,下图:

图(7)

看图(7),我们知道我们要写5次地址来确认我们要从nand flash中读的内容,第一次是列地址,第二次也是,这是因为如果只有1次,那么8位最大表示256,而一列的大小是2K,所以需要有两个列地址来代表。那么我们一共有256K页,所以需要3次8位的行地址来代表我们要读的是哪行,其实具体的还要看你的nand flash datasheet来决定如何给定地址列表。

 

图6的102行,是在循环判断是否是否已经准备好了,如果准备好了,我们才能再105行把这一整页得内容读到buf里面,注意看是从那个寄存器读取的哦,NF_DATA8_REG(nand flash数据寄存器);

109行禁止芯片,然后回到图(5)的nandll_read_blocks继续读下一页,直到读了0x3c000/page_shift个页为止,正好是192K,uboot的大小,并放到了buf中(0x57e00000内存)。

 

好了,分析完了