⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loadyaffs.c

📁 vivi烧写yaffs的文件!开发板公司没有提供!宝贵!
💻 C
字号:
/* * YAFFS: Yet another FFS. A NAND-flash specific file system.  * mkyaffs.c Format a chunk of NAND for YAFFS. * * Copyright (C) 2002 Aleph One Ltd. *   for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning <charles@aleph1.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * *  Acknowledgement: *  This file is crafted from nandtest.c by  Miguel Freitas (miguel@cetuc.puc-rio.br) *  and Steven J. Hill (sjhill@cotw.com) * * Overview: * Formatting a YAFFS device is very simple. Just erase all undamaged blocks.  * NB Don't erase blocks maked as damaged. */#define _GNU_SOURCE#include "config.h"#include "command.h"#include "machine.h"#include <priv_data.h>#include "mtd/mtd.h"#include "printk.h"#include "serial.h"#include "vivi_string.h"#include "md5.h"#include "xmodem.h"#include "ymodem.h"#include <string.h>#include "mtd/cfi.h"#include "mtd/bonfs.h"/*#include "memory.h"#include "serial.h"#include "vivi_string.h"#include <types.h>#include <errno.h>*/#define LOAD_TO_FLASH	1#define LOAD_TO_RAM	2extern struct mtd_info *mymtd;	/*struct mtd_info defined at include/mtd/mtd.h*/const char *mkyaffs_c_version = "$Id: mkyaffs.c,v 1.9 2005/10/11 23:39:56 charles Exp $";const char *vivi_loadyaffs_c_version = "thisway.diy@163.com, 2006.02.21";// countBits is a quick way of counting the number of bits in a byte.// ie. countBits[n] holds the number of 1 bits in a byte with the value n.static const char countBits[256] ={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8};static int modem_is(const char *mt){	if (strncmp("x", mt, 1) == 0) {		return X_MODEM;	} else if (strncmp("y", mt, 1) == 0) {		return Y_MODEM;	} else if (strncmp("z", mt, 1) == 0) {		return Z_MODEM;	} else {		return UNKNOWN_MODEM;	}}static size_tdownload_file(char *buf, size_t size, int modem, char *name){	switch (modem) {		case X_MODEM:#ifdef CONFIG_SERIAL_XMODEM			printk("Ready for downloading using xmodem...\n");			printk("Waiting...\n");			return xmodem_receive(buf, size);#else			printk("Not support XMODEM protocol by this vivi\n");#endif			break;		case Y_MODEM:#ifdef CONFIG_SERIAL_YMODEM			printk("Ready for downloading using ymodem...\n");			printk("Waiting...\n");			return ymodem_receive(buf, size, name);#else			printk("Not support YMODEM protocol by this vivi\n");#endif			break;		case Z_MODEM:			printk("Not support zmodem yet.\n");			break;		default:			printk("Not support this modem\n");			break;	}	return 0;}/* * loadyaffs_to_flash(): write buffer to MTD device, format as yaffs * * Arguments: *        ofs: offset to write. *        len: length of data to write. *        buf: location of buffers. *       flag: a flag of a mtd partiton. *  usemtdecc: use ecc of mtd, or ecc of yaffs */static int loadyaffs_to_flash(loff_t ofs, size_t len, const u_char *buf, int flag, int usemtdecc, size_t part_size){	unsigned long addr = 0;	unsigned long bad_addr = 0;	unsigned long erase_addr = 0;	unsigned long offset;	unsigned long flash_addr;    unsigned char oobbuf[16];    unsigned char ecc_code[6];    unsigned char* imgpage = NULL;    int eraseblocks = 0;    int badblocks = 0;    size_t retlen;	int imglen = 0;    int delay = 0;	struct mtd_oob_buf oob = {0, 16, (unsigned char *) &oobbuf};	struct mtd_info *mtd = mymtd;	struct erase_info instr;	if (mtd == NULL) {		printk("Error. invalid MTD informations\n");		return -1;	}	if (mtd->type != MTD_NANDFLASH)    {   		printk("Can't create yaffs on this flash, it isn't a nand flash\n");		return -1;	}	    /* 打开文件 */	    if (buf == NULL)    {        printk("Image not a found\n");        return -1;    }    /* xmodem以512字节为单位传输     * yaffs映象文件长度是528字节的整数倍     */    imglen = len - (len % 528);        /* 确定烧写位置 */    flash_addr = ofs;    imgpage = buf;    /* 确定flash的参数正确 */	if( !(mtd->oobsize == 16 && mtd->oobblock == 512))     {        printk("flash's params error: oobsize = %d, oobblcok = %d\n", mtd->oobsize, mtd->oobblock);        return -1;    }    printk("Flash params: oobsize = %d, oobblock = %d, erasesize = %d, partition size = %d\n", mtd->oobsize, mtd->oobblock, mtd->erasesize, part_size);	printk("Erasing and programming NAND with yaffs image\n");    printk(" Block erasing(addr/count) --- Block bad(addr/count) --- All count\n");    printk("-------------------------------------------------------------------\n");	for(addr = flash_addr; addr < flash_addr + part_size; addr += mtd->erasesize)	{		/* Read the OOB data to determine if the block is valid.		 * If the block is damaged, then byte 5 of the OOB data will		 * have at least 2 zero bits.		 */		oob.start = addr;		oob.length = 16;		oob.ptr = oobbuf;        /* read oob */        mtd->read_oob(mtd, oob.start, oob.length, &retlen, oob.ptr);				if(countBits[oobbuf[5]] < 7)		{            badblocks++;            bad_addr = addr;            printk("     0x%08x/%05d            0x%08x/%05d          %05d\r", erase_addr, eraseblocks, bad_addr, badblocks, eraseblocks + badblocks);                            delay = 100;            while(delay--);		}		else		{			/* Erase this block */                    	instr.addr = addr;        	instr.len = mtd->erasesize;    	    if (!(flag & MF_BONFS))             {                eraseblocks++;                erase_addr = addr;                printk("     0x%08x/%05d            0x%08x/%05d          %05d\r", erase_addr, eraseblocks, bad_addr, badblocks, eraseblocks + badblocks);    		    retlen = mtd->erase(mtd, &instr);        		if (retlen)                 {    	    		printk(" ... failed\n");    		    	return -1;        		}                printk("\r");            }						/* Do some programming, but not in the first block */						if(addr != flash_addr){				for(offset = 0; offset < mtd->erasesize; offset+=512)				{					if(imgpage < buf + imglen){						if (usemtdecc) {                            nand_calculate_ecc(imgpage, ecc_code);                            nand_calculate_ecc(&imgpage[256], &ecc_code[3]);							imgpage[512+8] = ecc_code[0];							imgpage[512+9] = ecc_code[1];							imgpage[512+10] = ecc_code[2];							imgpage[512+13] = ecc_code[3];							imgpage[512+14] = ecc_code[4];							imgpage[512+15] = ecc_code[5];						}                        						oob.start = addr+offset;						oob.length=16;						oob.ptr=&imgpage[512];                        /* write oob */                        mtd->write_oob(mtd, oob.start, oob.length, &retlen, oob.ptr);                        mtd->write(mtd, oob.start, 512, &retlen, imgpage);                        imgpage += 528;					}				}			}					}	}	/* All the tests succeeded */    printk("\nLoad yaffs OK:\n");	printk("Blocks scanned: %d, Blocks erased: %d, Blocks is bad: %d\n", eraseblocks + badblocks, eraseblocks, badblocks);	return 0;}/* * vivi command: * loadyaffs [-e] [ <partname> | <addr> ] <x|y|z> */void command_loadyaffs(int argc, const char **argv){	char *buf = (char *)RAM_BASE;	//loff_t to; 	unsigned long to;	/* is declared to long-long type ? */	size_t size;	int modem = 0;	int where_to = 0;	int ret;	size_t retlen;	mtd_partition_t *dst_part;	int flag;	char file_name[255] = { 0, };    int usemtdecc = 0;        if (argc == 3)        usemtdecc = 0;    else if ((argc == 4) && (strcmp(argv[1], "-e") == 0))        usemtdecc = 1;    else    {        goto invalid_cmd;    }	dst_part = get_mtd_partition(argv[(argc == 3)?1:2]);	if (dst_part == NULL)     {        printk("Can't find partition %s\n", argv[(argc == 3)?1:2]);        return;	}	to = dst_part->offset;    size = dst_part->size;    flag = dst_part->flag;	modem = modem_is((const char*)argv[(argc == 3)?2:3]);	where_to = LOAD_TO_FLASH;	/* download a file */	retlen = download_file(buf, size, modem, file_name);	/* hacked by nandy. delay for serial output */	{ int i = 0x10000; while (i > 0) i--; }	if (retlen == 0) {		printk("Failed downloading file\n");		return;	}	printk("Downloaded file at 0x%08lx, size = %d bytes\n", buf, retlen);	switch (where_to) {	case LOAD_TO_FLASH:		if (retlen > size) {			printk("An image size is too large to write flash. \				wanted = 0x%08lx, loaded = 0x%08lx\n", size, retlen);			return;		}		if (flag & MF_ISRAM) {			printk("Ooops, actually this partition is ram. It's tweak...!\n");			return;		}		ret = loadyaffs_to_flash((loff_t)to, retlen, buf, flag, usemtdecc, size);		break;	case LOAD_TO_RAM:		break;	}	if (modem == Y_MODEM)		check_md5sum(buf, retlen, file_name);	return;invalid_cmd:	printk("invalid 'loadyaffs' command: too few(many) arguments\n");	printk("\nUsage:\n");	printk("  loadyaffs [-e] <partname> <x|y|z>\n");	printk("    -e: use ecc of mtd\n");	return;}user_command_t loadyaffs_cmd = {	"loadyaffs",	command_loadyaffs,	NULL,	"loadyaffs {...}\t\t\t-- Load a yaffs image to Flash"};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -