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

📄 cmd_bon.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
字号:
/* * vivi/drivers/mtd/nand/bon.c  * * Based on vivi/util/imagewrite * * $Id: bon.c,v 1.12 2003/03/10 10:32:56 nandy Exp $ * * 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. * * Description: Simple management routines for the bon file system. * */#include <common.h>#include <command.h>#include <malloc.h>#include <asm/io.h>#if (CONFIG_COMMANDS & CFG_CMD_NAND)#include <linux/mtd/nand.h>#include <linux/mtd/nand_ids.h>#include <jffs2/jffs2.h>#include <linux/ctype.h>#define NANDRW_READ	0x01#define NANDRW_WRITE	0x00#define NANDRW_JFFS2	0x02extern struct nand_chip nand_dev_desc[];extern int nand_write_oob(struct nand_chip* nand, size_t ofs, size_t len, size_t * retlen, const u_char * buf);extern int nand_rw (struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf);extern int nand_erase(struct nand_chip* nand, size_t ofs, size_t len, int clean);extern int check_block1(struct nand_chip* nand, unsigned long pos);extern void getchar(void);#define MAX_PART 		5#define PARTITION_OFFSET	(~0)#define IS_MTD  1#define IS_BON  0#define PARTNAMELEN	12typedef struct {	char	      PartName[PARTNAMELEN];	unsigned long offset;	unsigned long size;	unsigned long flag;	unsigned long num_bad_block;	unsigned short *bad_blocks;} bon_partition_t;const char bon_part_magic[8] = {'M', 0, 0, 'I', 0, 'Z', 'I', 0};bon_partition_t parts[MAX_PART];int num_part = 0;#define NAND_SECTOR_SIZE	512#define NAND_OOB_SIZE		16static void mark_bad(struct nand_chip *mtd, unsigned long offset){	char oobbuf[NAND_OOB_SIZE];	int	retlen;	memset (oobbuf, 0xff, NAND_OOB_SIZE);	oobbuf[5]=0;	nand_write_oob(mtd, offset, NAND_OOB_SIZE, &retlen, oobbuf);}int erase_bon(struct nand_chip *mtd, int bonnum){	if(!(bonnum >= 0 && bonnum < num_part))		return -1;	nand_erase (mtd, parts[bonnum].offset, parts[bonnum].size, 1);	return 0;}int write_bon_image(struct nand_chip *mtd, int PartNum, char *src, long size){	int bad_block_nr = 0;	/* NAND_SECTOR_SIZE*32 > meminfo.erasesize */	char buf[NAND_SECTOR_SIZE*32];	int retlen;	int i;	long offset;	printf("size = %lx bon=%d\n", size, PartNum - 1);	if(!(PartNum  >= 1 && PartNum <= num_part))	{		printf("bad bon num!\n");		return -1;	}	i = PartNum - 1;	if (size > parts[i].offset + parts[i].size - parts[i].num_bad_block * 32 * NAND_SECTOR_SIZE) 	{		printf("image is too big for this partition\n");		return -1;	}		erase_bon(mtd, i);	offset = parts[i].offset;	memcpy(buf, src, mtd->erasesize);	while (size > 0) 	{		if(nand_rw(mtd, NANDRW_WRITE, offset, mtd->erasesize, &retlen, buf) == 0)		{			size -= mtd->erasesize;			src += mtd->erasesize;			if (size > 0)				memcpy(buf, src, mtd->erasesize);		} 		else 		{			int k;			int block_nr = (offset - parts[i].offset) / mtd->erasesize;			for (k = 0; k < parts[i].num_bad_block; k++) 			{				if (block_nr == parts[i].bad_blocks[k]) break;			}			if (k == parts[i].num_bad_block) 				printf("*** warning: new bad block in %d\n", block_nr);			bad_block_nr++;		}		offset += mtd->erasesize;	}	printf("bad_block = %d\n", bad_block_nr);	return 0;}int read_bon_image(struct nand_chip *mtd, int PartNum, char *src, long size){	int bad_block_nr = 0;	int retlen;	int i;	long offset;	printf("size = %lx\n", size);	if(!(PartNum  >= 1 && PartNum <= num_part))	{		printf("bad bon num!\n");		return -1;	}	i = PartNum - 1;	if (size > parts[i].offset + parts[i].size - parts[i].num_bad_block * 32 * NAND_SECTOR_SIZE) 	{		printf("image is too big for this partition\n");		return -1;	}		offset = parts[i].offset;	while (size > 0) 	{		if(nand_rw(mtd, NANDRW_READ, offset, mtd->erasesize, &retlen, src) == 0)		{			size -= mtd->erasesize;			src += mtd->erasesize;		} 		else 		{			int k;			int block_nr = (offset - parts[i].offset) / mtd->erasesize;			for (k = 0; k < parts[i].num_bad_block; k++) 			{				if (block_nr == parts[i].bad_blocks[k]) break;			}			if (k == parts[i].num_bad_block) 				printf("*** warning: new bad block in %d\n", block_nr);			bad_block_nr++;		}		offset += mtd->erasesize;	}	printf("bad_block = %d\n", bad_block_nr);	return 0;}#define	 MAXTRY 5int read_bon_partition(struct nand_chip *mtd){	int i, k;	char buf[NAND_SECTOR_SIZE];	unsigned int *s;	unsigned long offset = PARTITION_OFFSET;	int retlen;	if (offset > mtd->totlen - mtd->erasesize)		offset = mtd->totlen - mtd->erasesize;	for(i = 0;i < MAXTRY; i++)	{		if(nand_rw(mtd, NANDRW_READ, offset, NAND_SECTOR_SIZE, &retlen, buf))		{			printf("read error: mark bad: offset = %lX\n", offset);			offset -= mtd->erasesize;			continue;		}		break;	}	if (strncmp(buf, bon_part_magic, 8) != 0)	{		num_part = 0;		return -1;	}	s = (unsigned int *)(buf + 8);	num_part = *s++;	for (i = 0; i < num_part; i++) {		strncpy(parts[i].PartName, (char *)s, PARTNAMELEN-1);		parts[i].PartName[PARTNAMELEN - 1] = 0;		s += PARTNAMELEN / sizeof(int);		parts[i].offset = *s++;		parts[i].size = *s++;		parts[i].flag = *s++;	}	for (i = 0; i < num_part; i++) {		parts[i].num_bad_block = *s++;		if (parts[i].num_bad_block) {			parts[i].bad_blocks = mmalloc(parts[i].num_bad_block * sizeof(unsigned int));			for (k = 0; k < parts[i].num_bad_block;k++) {				parts[i].bad_blocks[k] = *s++;			}		} else {			parts[i].bad_blocks = 0;		}	}		return 0;}int read_size(char *s, unsigned long *size){    	int is_ok = -1;	while (isdigit(*s)) {	    	is_ok = 0;		(*size) = (*size) * 10 + *s - '0';		s++;	}	if (is_ok < 0)	return -1;	if (*s == 'M' || *s == 'm') (*size) *= 1024*1024;	else if (*s == 'K' || *s == 'k') (*size) *= 1024;	return 0;}int write_partition(struct nand_chip *mtd, unsigned long offset, unsigned long *PartInfoOff){	char buf[NAND_SECTOR_SIZE];	unsigned int *s;	int i, k;	size_t retlen;	*PartInfoOff = 1;	for(i = 0; i < MAXTRY; i++)	{		if(nand_rw(mtd, NANDRW_READ, offset, NAND_SECTOR_SIZE, &retlen, buf))		{			if(nand_rw(mtd, NANDRW_READ, offset, NAND_SECTOR_SIZE, &retlen, buf))			{				printf("read error: mark bad: offset = %lX\n", offset);				offset -= mtd->erasesize;				*PartInfoOff ++;				continue;			}		}		break;	}	if(nand_erase (mtd, offset, mtd->erasesize, 1) == -2){		if(nand_erase (mtd, offset, mtd->erasesize, 1) == -2){			printf("erase error: mark bad: offset = %lX\n", offset);			mark_bad(mtd, offset);			return -1;		}	}	memcpy(buf, bon_part_magic, 8);	s = (unsigned int *)(buf+8);	*s++ = num_part;	for (i = 0; i < num_part; i++) {		for(k = 0; k < PARTNAMELEN / sizeof(int); k++)			*s++ = *((int *)(parts[i].PartName + k * sizeof(int)));		*s++ = parts[i].offset;		*s++ = parts[i].size;		*s++ = parts[i].flag;	}	for (i = 0; i < num_part; i++) {		*s++ = parts[i].num_bad_block;		for (k = 0; k < parts[i].num_bad_block; k++) {			*s++ = parts[i].bad_blocks[k];			printf("k = %d block = %d\n", k, parts[i].bad_blocks[k]);		}	}	//read two	if(nand_rw(mtd, NANDRW_WRITE, offset, NAND_SECTOR_SIZE, &retlen, buf))	{		return -1;	}	if (retlen != NAND_SECTOR_SIZE) {		printf("write error: offset = %lu %x %x\n", offset, retlen, NAND_SECTOR_SIZE);		return -1;	}	return 0;}int write_partition_table(struct nand_chip *mtd){	int i, k;	unsigned long offset = PARTITION_OFFSET;	unsigned long PartInfoOff;		if (offset > mtd->totlen - mtd->erasesize)		offset = mtd->totlen - mtd->erasesize;	if (write_partition(mtd, offset, &PartInfoOff) != 0) {		printf("can not write bon partition info\n");		return -1;	}	for (i = 0; i < num_part; i++) {		printf("\t\t---part:%d----\n", i+1);		printf("\tpartname= %s\n", parts[i].PartName);		printf("\toffset = %ld\n", parts[i].offset);		if(!num_part)			parts[i].size -=  32 * NAND_SECTOR_SIZE;		printf("\tsize = %ld\n", parts[i].size - parts[i].num_bad_block * 32 * NAND_SECTOR_SIZE);		printf("\tbad_block_count = %ld\n", parts[i].num_bad_block);		printf("\tflag = %ld\n", parts[i].flag);		if(parts[i].num_bad_block)		{		printf("\tbad_block_num = ");		for (k = 0; k < parts[i].num_bad_block; k++) {			printf(" %d", parts[i].bad_blocks[k]);		}		printf("\n");		}	}	return 0;}void display_partition_table(void){	int 	i = 0;	if (read_bon_partition(nand_dev_desc)) {	   	printf("Invalid partition table info\n");		return;	}	printf("BON info. (%d partitions)\n", num_part);	printf("No:        name     offset       size(BYTE)    flags    bad     size(K)\n");	printf("-----------------------------------------------------------------------\n");	for (i = 0; i < num_part; i++) {	  printf("%2d: %12s  0x%8lx\t  %8ld  %-7s    %3ld       %ld\n",		 i + 1, parts[i].PartName, parts[i].offset, parts[i].size,		 parts[i].flag ? "bon":"non_bon", parts[i].num_bad_block, parts[i].size / 1024);	}}static void display_help(void){	printf("Usage:\n");	printf("\tsjpgpart info: show available part on nand\n");	printf("\tsjpgpart creat partsize(unit = M or K) partname {non_bon_flag = 1}: craet bon partion\n");	printf("\tsjpgpart write partnum srcoff writesize: write image to bon partion, unit = byte\n");	printf("\tsjpgpart read partnum objoff readsize: read image form bon partion, unit = byte\n");}void check_bad_block(struct nand_chip *mtd){	int i;	unsigned short bad_block[1024];	for (i = 0; i < num_part; i++) {		ulong offset = parts[i].offset;		ulong end = parts[i].size + parts[i].offset;		int num_bad = 0;		int bad;		if(end > mtd->totlen - mtd->erasesize)		{			end = mtd->totlen - mtd->erasesize;			parts[i].size = end - parts[i].offset;		}		printf("part = %d end = %ld\n", i, end);		while (offset < end) {			bad = check_block1(mtd, offset);			if (bad) {				bad_block[num_bad] = (offset - parts[i].offset) /\							mtd->erasesize;				num_bad++;				printf("%lX: is bad\n", offset);			}			offset += mtd->erasesize;		}		parts[i].num_bad_block = num_bad;#if 0 //  ???? - bushi		parts[i].flag = 0;#endif		if (num_bad) {			parts[i].bad_blocks = mmalloc(num_bad * sizeof(unsigned short));			memcpy(parts[i].bad_blocks, bad_block, num_bad * 2);			parts[i].size = end - parts[i].offset - num_bad * mtd->erasesize;		}		else			parts[i].bad_blocks = NULL;	}}static void command_part(int argc, const char **argv){	struct nand_chip *mtd = nand_dev_desc;	unsigned long ret;	int partnum;	long offset;	long size;	if ((argc == 2) &&		((strncmp("info", argv[1], 4) == 0) ||		 (strncmp("show", argv[1], 4) == 0))) {		display_partition_table();		return;	}	read_bon_partition(nand_dev_desc);	/* write partition table */	if(strncmp("creat", argv[1], 5) == 0)	{		if(num_part >= 10)		{         		printf("only can create 10 partitions!\n");			return;		}		printf("creating partition\n");		ret = 0;		if(read_size((char *)argv[2], &ret) < 0) 				return;			parts[num_part].size = ret;		if(!num_part)			parts[num_part].offset = mtd->totlen - mtd->erasesize - ret;		else			parts[num_part].offset = parts[num_part - 1].offset - ret;					printf("size = %ld\n", parts[num_part].size);		memset(parts[num_part].PartName, 0, PARTNAMELEN);		strncpy(parts[num_part].PartName, argv[3], PARTNAMELEN - 1);		printf("name - %s\n", parts[num_part].PartName, argc);		if(argc > 4)			parts[num_part].flag = 0;		else			parts[num_part].flag = 1;		num_part++;		printf("check bad block\n");		check_bad_block(mtd);		write_partition_table(mtd);	}	else if(strncmp("write", argv[1], 5) == 0)	{		printf("Writing Image to partition\n");		partnum = (int)simple_strtoul(argv[2], NULL, 10);		offset = (int)simple_strtoul(argv[3], NULL, 16);		size = (int)simple_strtoul(argv[4], NULL, 16);				printf("part num =%d\n", partnum);		printf("source offset = %lx\n", offset);		write_bon_image(mtd, partnum, (char *)offset, size);			}	else if(strncmp("read", argv[1], 4) == 0)	{		printf("reading Image form partition\n");		partnum = (int)simple_strtoul(argv[2], NULL, 10);		offset = (int)simple_strtoul(argv[3], NULL, 16);		size = (int)simple_strtoul(argv[4], NULL, 16);		printf("source offset = %lx\n", offset);		read_bon_image(mtd, partnum, (char *)offset, size);	}	else		printf("invalid sjpgpart command\n");}void command_bon(cmd_tbl_t *cmdtp, int flag, int argc, const char **argv){	if (strncmp("help", argv[1], 4) == 0) {		display_help();		return;	}	if (argc == 1) { 		display_help();		return;	}	command_part(argc, argv);	return;}U_BOOT_CMD(	part,	6,	1,	command_bon,	"part- part sub-system\n",	"   info: show available part on nand\n"	"            creat partsize(unit = M or K) partname {non_bon_flag = 1}: craet bon partion\n" 	"            write partnum srcoff size: write image to bon partion, unit = byte\n" 	"            read partnum objoff size: read image from bon partion, unit = byte\n");#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */

⌨️ 快捷键说明

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