s3c2416解决无法下载大于60M文件系统

来源:互联网 发布:c语言无限循环代码 编辑:程序博客网 时间:2024/06/11 11:39

硬件配制内存64M,nandflash 128M,我的u-boot版本为1.3.4

由于内存太小,无法下载大于60M的文件系统,我这里说下如何从TF更新大于60M的文件系统。

首先从TF卡 启动更新系统你需要移植fat,mmc相关支持,这里我已经移植好了具体过程我就不说了.这些移植完成后。

最开始是可以使用如下命令进行更新的:

fatload mmc 0 0xc0000000 /gzsd/u-boot.bin; nand erase bios; nand write.jffs2 0xc0000000 bios $(filesize)
bios为u-boot分区信息。60M文件之所以无法下载是因为内存不够引起的,所以首先要找到读文件是在哪里,跟踪代码最后找到fat.c文件。

在函数get_contents中有这样几条代码:

/* get remaining clusters */if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}/* get remaining bytes */gotsize += (int)actsize;filesize -= actsize;buffer += actsize;actsize= filesize;if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}
具体读的过程就是在get_cluster函数里

static intget_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size){int idx = 0;__u32 startsect;if (clustnum > 0) {startsect = mydata->data_begin + clustnum*mydata->clust_size;} else {startsect = mydata->rootdir_sect;}FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) {FAT_DPRINT("Error reading data\n");return -1;}if(size % FS_BLOCK_SIZE) {__u8 tmpbuf[FS_BLOCK_SIZE];idx= size/FS_BLOCK_SIZE;if (disk_read(startsect + idx, 1, tmpbuf) < 0) {FAT_DPRINT("Error reading data\n");return -1;}buffer += idx*FS_BLOCK_SIZE;memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE);return 0;}return 0;}
接下来我主要对这两个函数进行修改,我的实现过程是将文件系统分次读写,先读20几M然后开始写到flash里,然后在读20几M写到flash里,反复这样的操作.

首先在文件前面增加向个全局变量和宏定义

#define BUF_SIZE(2112*1024*10)#define B_ADDR0x0#define K_ADDR0x300000#define R_ADDR0x700000static long nandaddr=0;static long memaddr=0xc0000000;static int wnandflags = 0;
其中BUF_SIZE为每次读写的字节,有一点需要注意这里的大小不是可以任意修改。在写yaffs文件的时候有一个大小的判断。具体请看u-boot源码下的drivers/mtd/nand/nand_util.c

函数:

int nand_write_skip_bad_yaffs里面有如下代码:

if (*length % (nand->writesize + nand->oobsize)) {*length = (*length / (nand->writesize + nand->oobsize)+1)*(nand->writesize + nand->oobsize);}
length为你写的文件的大小,而其中
nand->writesize + nand->oobsize
就是2112字节

同时BUF_SIZE还必需满足以下两个条件:

1.必需是512的倍数,因为TF卡里一个扇区是512字节,如果不是512字节可能导致数据最后加起来不对

2.必需是2*1024的倍数,yaffs文件好像不需要满足这个,这个只针对u-boot和内核,因为nandflash是以2K对齐的,如果内核大于BUF_SIZE了这个就需要用到了。

B_ADDR u-boot在nand flash里的起始地址 K_ADDR内核在nand flash里的起始地址 R_ADDR为文件系统在nand flash里的起始地址.

这两个函数修改后如下:

static intgzsd_get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size){int idx = 0;__u32 startsect;char cmd_buf[200];unsigned long wsize;unsigned long tmpmem,tmpnand;int times,i,tmpsize;__u8 *dmem=(unsigned char *)0xc0000000;if (clustnum > 0) {startsect = mydata->data_begin + clustnum*mydata->clust_size;} else {startsect = mydata->rootdir_sect;}FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);if(size > BUF_SIZE) {times = size / BUF_SIZE;tmpmem = memaddr;tmpnand = nandaddr;tmpsize = BUF_SIZE;for(i=0;i<times;i++) {if (disk_read(startsect, tmpsize/FS_BLOCK_SIZE , dmem) < 0) {FAT_DPRINT("Error reading data\n");return -1;}if(tmpsize % FS_BLOCK_SIZE)printf("*****************************\n");if(wnandflags) {sprintf(cmd_buf, "nand write.yaffs 0x%x 0x%x 0x%x", tmpmem, tmpnand, tmpsize);printf("nand write.yaffs 0x%x 0x%x 0x%x", tmpmem, tmpnand, tmpsize);run_command(cmd_buf, 0);}else {sprintf(cmd_buf, "nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, tmpsize);printf("nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, tmpsize);run_command(cmd_buf, 0);}//buffer += BUF_SIZE;startsect += tmpsize/FS_BLOCK_SIZE;//tmpmem += tmpsize;tmpnand += tmpsize;}if(size % BUF_SIZE) {tmpsize = size % BUF_SIZE;if (disk_read(startsect, tmpsize/FS_BLOCK_SIZE , dmem) < 0) {FAT_DPRINT("Error reading data\n");return -1;}if(tmpsize % FS_BLOCK_SIZE) {__u8 tmpbuf[FS_BLOCK_SIZE];idx= tmpsize/FS_BLOCK_SIZE;if (disk_read(startsect + idx, 1, tmpbuf) < 0) {FAT_DPRINT("Error reading data\n");return -1;}dmem += idx*FS_BLOCK_SIZE;memcpy(dmem, tmpbuf, tmpsize % FS_BLOCK_SIZE);}if(wnandflags) {wsize = tmpsize;sprintf(cmd_buf, "nand write.yaffs 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);printf("nand write.yaffs 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);run_command(cmd_buf, 0);}else {if(tmpsize % (2*1024) != 0)wsize = ((tmpsize/(2*1024)) + 1)*(2*1024);elsewsize = tmpsize;sprintf(cmd_buf, "nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);printf("nand write.jffs2 0x%x 0x%x 0x%x", tmpmem, tmpnand, wsize);run_command(cmd_buf, 0);}}}else { // < BUF_SIZEif (disk_read(startsect, size/FS_BLOCK_SIZE , dmem) < 0) {FAT_DPRINT("Error reading data\n");return -1;}if(size % FS_BLOCK_SIZE) {__u8 tmpbuf[FS_BLOCK_SIZE];idx= size/FS_BLOCK_SIZE;if (disk_read(startsect + idx, 1, tmpbuf) < 0) {FAT_DPRINT("Error reading data\n");return -1;}dmem += idx*FS_BLOCK_SIZE;memcpy(dmem, tmpbuf, size % FS_BLOCK_SIZE);}if(wnandflags) {wsize = size;sprintf(cmd_buf, "nand write.yaffs 0x%x 0x%x 0x%x", memaddr, nandaddr, wsize);printf("nand write.yaffs 0x%x 0x%x 0x%x", memaddr, nandaddr, wsize);run_command(cmd_buf, 0);}else {if(size % (2*1024) != 0)wsize = ((size/(2*1024)) + 1)*(2*1024);elsewsize = size;sprintf(cmd_buf, "nand write.jffs2 0x%x 0x%x 0x%x", memaddr, nandaddr, wsize);printf("nand write.jffs2 0x%x 0x%x 0x%x", memaddr, nandaddr, wsize);run_command(cmd_buf, 0);}}return 0;}/* * Read at most 'maxsize' bytes from the file associated with 'dentptr' * into 'buffer'. * Return the number of bytes read or -1 on fatal errors. */static longget_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,     unsigned long maxsize){unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;__u32 curclust = START(dentptr);__u32 endclust, newclust;unsigned long actsize;FAT_DPRINT("Filesize: %ld bytes\n", filesize);if (maxsize > 0 && filesize > maxsize) filesize = maxsize;FAT_DPRINT("Reading: %ld bytes\n", filesize);printf("Reading: %ld bytes\n", filesize);if(filesize < (1*1024*1024)) {nandaddr = B_ADDR;wnandflags = 0;}else if((filesize > (1*1024*1024)) && (filesize < (10*1024*1024))) {nandaddr = K_ADDR;wnandflags = 0;}else if(filesize > (10*1024*1024)) {nandaddr = R_ADDR;wnandflags = 1;}memaddr = 0xc0000000;actsize=bytesperclust;endclust=curclust;do {/* search for consecutive clusters */while(actsize < filesize) {newclust = get_fatent(mydata, endclust);if((newclust -1)!=endclust)goto getit;if (CHECK_CLUST(newclust, mydata->fatsize)) {FAT_DPRINT("curclust: 0x%x\n", newclust);FAT_DPRINT("Invalid FAT entry\n");return gotsize;}endclust=newclust;actsize+= bytesperclust;}/* actsize >= file size */actsize -= bytesperclust;#if 1#if 0/* get remaining clusters */if (gzsd_get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}/* get remaining bytes */gotsize += (int)actsize;filesize -= actsize;//buffer += actsize;nandaddr += actsize;//memaddr += actsize;actsize= filesize;if (gzsd_get_cluster(mydata, endclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}#else/* get remaining clusters */if (gzsd_get_cluster(mydata, curclust, buffer, filesize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}#endif#else/* get remaining clusters */if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}/* get remaining bytes */gotsize += (int)actsize;filesize -= actsize;buffer += actsize;actsize= filesize;if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}#endifgotsize+=actsize;return gotsize;getit:if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {FAT_ERROR("Error reading cluster\n");return -1;}gotsize += (int)actsize;filesize -= actsize;buffer += actsize;curclust = get_fatent(mydata, endclust);if (CHECK_CLUST(curclust, mydata->fatsize)) {FAT_DPRINT("curclust: 0x%x\n", curclust);FAT_ERROR("Invalid FAT entry\n");return gotsize;}actsize=bytesperclust;endclust=curclust;} while (1);}
get_cluster不作修改,因为还有一个地方需要用到,这里新增加一个gzsd_get_cluster函数,将nand的写操作也增加进去了,现在只需要执行:

fatload mmc 0 0xc0000000 /gzsd/root.bin就可以完成烧写.

原创粉丝点击