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

📄 flashimage.c

📁 基于xscale的远程更新nandflash设备
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007  Jiong Zhao <gohigh@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* flashimage.c  */#include <limits.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <stdint.h>#include <sys/ioctl.h>#include <sys/syscall.h>#include <fcntl.h>#include <string.h>#include <errno.h>#include <error.h>#include <time.h>#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/reboot.h>#include <linux/reboot.h>#include <byteswap.h>#include "mtd.h"#define FPRINTF fprintf/* Define the machine's endian type. If we operate on Big Endian data, * then we use READ32_BE(X) and STORE32_BE(X). If we operate on Little * Endian data, then we should use READ32_LE(X) and STORE32_LE(X). */#define __BYTE_ORDER __LITTLE_ENDIAN     // Host machine - i386 type.//#define __BYTE_ORDER __BIG_ENDIAN          // Target machine - ARM type.#if __BYTE_ORDER == __BIG_ENDIAN           // Program used on ARM type.#define STORE32_LE(X)		bswap_32(X)#define READ32_LE(X)		bswap_32(X)#define STORE32_BE(X)		(X)#define READ32_BE(X)		(X)#elif __BYTE_ORDER == __LITTLE_ENDIAN      // Program used on i386 type.#define STORE32_LE(X)		(X)#define READ32_LE(X)		(X)#define STORE32_BE(X)		bswap_32(X)#define READ32_BE(X)		bswap_32(X)#else#error unkown endianness!#endifuint32_t crc32(uint32_t crc, char *buf, size_t len);/**********************************************************************/#define PAK_MAGIC	0x41435358		/* "XSCA" */#define PAK_VERSION	1#define PAK_MAX_LEN	0xB00000#define MAX_NAME_LEN	15#define MAX_PAK_IMAGES  5#define MAX_ARGS 8#define BUFSIZE (128 * 1024)        /* 0x00020000 */#define HDBUFSIZE 512#define INIT_CRC 0xFFFFFFFFstruct img_header {	uint32_t offset;	/* image begin offset in this pack file. -1 end.*/	uint32_t len;		/* length of pure file. */	uint32_t mtdofs;         /* null if this is the last. */		uint32_t mtdno;		/* in /proc/mtd: dev */	char mtdname[MAX_NAME_LEN+1];          /* in /proc/mtd: name  */	char filename[MAX_NAME_LEN+1];         /* filename when packed (w/o path) */} img_header_t ;		struct pak_header {	uint32_t magic;		/* "XSCA" */	uint32_t len;		/* Length of file including header */	uint32_t crc32;		/* 32-bit CRC from flag_version to end of file */	uint32_t icount;	/* Total image file number. */	struct img_header img[MAX_PAK_IMAGES];	} pheader ;struct proc_mtd_table {	char mtd[8];	uint32_t size;	uint32_t erasesize;	char name[20];	char devfile[20];} ptable[MAX_MTD_DEVICES];char hdbuf[HDBUFSIZE];char buf[BUFSIZE];int buflen;int quiet ;int unlocked;char *erase[MAX_ARGS];char *device;char *imgfile;/**********************************************************************//* The header occupis 256 bytes. The first image file is stored beginning *//* from this location. Only 5 image files can be stored together. */void usage(void) __attribute__ (( __noreturn__ ));int my_mtd_open(const char *mtd, int flags);int get_proc_mtdno(const char *name);int image_crc32_check(int imgfd){	uint32_t n = 0;    	uint32_t crc = INIT_CRC ;   /* 0xFFFFFFFF, so no swap needed.  */	// Get the packed file header (pheader) and check the CRC.	while ((n = read(imgfd, buf, BUFSIZE))) {		if (crc == INIT_CRC) {			pheader = *(struct pak_header *)buf ;			n -= offsetof(struct pak_header, icount);			crc = crc32(crc, &buf[offsetof(struct pak_header, icount)], n);		} else {			crc = crc32(crc, buf, n);		}	}	/* The magic number is a special case. It should always  be a 	 * little endian type */	if (READ32_LE(pheader.magic) != PAK_MAGIC) { 	        if ( READ32_BE(pheader.magic) != PAK_MAGIC) {				fprintf(stderr, "The file's type is incorrect.\n"); 			return 0;		} else {			fprintf(stderr, "=== WARNING: magic swapped. Should be an old image file.\n");		}       	}    	if (crc != READ32_BE(pheader.crc32)) {		fprintf(stderr, "Current crc and crc in file header:%x, %x\n", crc, READ32_BE(pheader.crc32));		fprintf(stderr, "Packed file CRC check error.\n");		return 0;	} ;	lseek(imgfd, 0L, 0);	return 1;}int	show_imgfile_info(void){	int i;	// we need list all the info in imgfile.	fprintf(stderr, "\nThe packed file \"%s\" contains %d image(s) as bellow:\n", imgfile, READ32_BE(pheader.icount));       	for (i=0; i < READ32_BE(pheader.icount); i++) {		//fprintf(stderr, "The device %s has img in imgsfile:\n", device);		fprintf(stderr, "----------------------------------\n");   		fprintf(stderr, "Orignal image name: \"%s\"\n", pheader.img[i].filename);		fprintf(stderr, "Image file length : %d\n", READ32_BE(pheader.img[i].len));		fprintf(stderr, "Name for this MTD : \"%s\"\n", pheader.img[i].mtdname);		fprintf(stderr, "Offset in this MTD: 0x%08X\n", READ32_BE(pheader.img[i].mtdofs));	}		return 0;	}			int	check_device_In_imgfile(char *device, int show){	int mtdno, found = 0;    	int i ;	// Check to see if 'device' has a image in the ImgsFile.	// If there has one or more, we list the info of these imgs.	if (!device)		return 0;    	mtdno = -1 ;	sscanf(device, "mtd%d", &mtdno);	found = 0;	for (i=0; i < READ32_BE(pheader.icount); i++) {		if ((strcmp(device, pheader.img[i].mtdname)==0)||(mtdno == READ32_BE(pheader.img[i].mtdno))){			// we need only list this specified img info.            if (found == 0) {				found = 1;				if (show){					fprintf(stderr, "The packed file \"%s\" contains images for the device %s :\n", imgfile, device);				} else return 1;			}			if (show) {				fprintf(stderr, "-------- Image %d --------------------\n",i+1);				fprintf(stderr, "Orignal image name: \"%s\"\n", pheader.img[i].filename);				fprintf(stderr, "Image file length : %d\n", READ32_BE(pheader.img[i].len));				fprintf(stderr, "Name for this MTD : \"%s\"\n", pheader.img[i].mtdname);	 			fprintf(stderr, "Offset in this MTD: 0x%08X\n", READ32_BE(pheader.img[i].mtdofs));			} else return 1;		}	}    if (found == 0) {		fprintf(stderr, "The packed file \"%s\" does't contain image for device %s.\n", imgfile, device);		exit(1);	}    return 1;}int image_mtd_check(int imgfd, const char *device){	int i, mtdno;	char *devfile ;    mtdno = -1 ;	sscanf(device, "mtd%d", &mtdno);	for (i=0; i < READ32_BE(pheader.icount); i++) {		if ((strcmp(device, pheader.img[i].mtdname)==0)||(mtdno == READ32_BE(pheader.img[i].mtdno))){			// we need only list this specified img info.			mtdno = READ32_BE(pheader.img[i].mtdno);			if (mtdno == get_proc_mtdno(device)){				devfile = ptable[mtdno].devfile;				fprintf(stderr, "device %s's devfile is: %s\n", device, devfile);			    /* ...... */			}					}	}		return 1;}int my_mtd_check(char *device){	struct mtd_info_user mtdInfo;	int fd;	if (device == NULL)        return 1;	fd = my_mtd_open(device, O_RDWR|O_SYNC);	if (fd < 0) {		fprintf(stderr, "Could not open mtd device: %s\n",device);		return 0;	}	if (ioctl(fd, MEMGETINFO, &mtdInfo)) {		fprintf(stderr, "Could not get MTD device info from %s\n", device);		close(fd);		return 0;	}	close(fd);	return 1;}int mtd_unlock(const char *mtd){	int fd;	struct mtd_info_user mtdInfo;	struct erase_info_user mtdLockInfo;	fd = my_mtd_open(mtd, O_RDWR | O_SYNC);	if (fd < 0) {		fprintf(stderr, "Could not open mtd device: %s\n", mtd);		exit(1);	}	if (ioctl(fd, MEMGETINFO, &mtdInfo)) {		fprintf(stderr, "Could not get MTD device info from %s\n", mtd);		close(fd);		exit(1);	}	mtdLockInfo.start = 0;	mtdLockInfo.length = mtdInfo.size ;	if (ioctl(fd, MEMUNLOCK, &mtdLockInfo)) {		close(fd);		return 0;	}	close (fd);	return 0;}int my_mtd_open(const char *device, int flags){	int mtdno;	if (device==NULL)		return (-1);	if ((mtdno = get_proc_mtdno(device))<0)		return (-1);    return open(ptable[mtdno].devfile, flags);}int mtd_erase(const char *mtd){	int fd;	struct mtd_info_user mtdInfo;	struct erase_info_user mtdEraseInfo;	fd = my_mtd_open(mtd, O_RDWR | O_SYNC);	if (fd < 0) {		fprintf(stderr, "Could not open mtd device: %s\n", mtd);		exit(1);	}	if (ioctl(fd, MEMGETINFO, &mtdInfo)) {		fprintf(stderr, "Could not get MTD device info from %s\n", mtd);		close(fd);		exit(1);	}	mtdEraseInfo.length = mtdInfo.erasesize;	for (mtdEraseInfo.start = 0 ; mtdEraseInfo.start < mtdInfo.size; 			mtdEraseInfo.start += mtdInfo.erasesize) {		ioctl(fd, MEMUNLOCK, &mtdEraseInfo);		if (ioctl(fd, MEMERASE, &mtdEraseInfo))			fprintf(stderr, "Failed to erase block on %s at 0x%x\n", mtd, mtdEraseInfo.start);	}	close(fd);	return 0;}int my_mtd_write(int imgfd, int pt_id, int img_id){	int fd;	char *device ;	char *fname ;	int mtdno;	uint32_t res, rn, wr,rd,er;	uint32_t mtdofs, offset;	uint32_t mtdlen ;	struct mtd_info_user mtdInfo ;	struct erase_info_user mtdEraseInfo ;	device = ptable[pt_id].mtd ;	mtdno = get_proc_mtdno(device);	offset = READ32_BE(pheader.img[img_id].offset);	mtdofs = READ32_BE(pheader.img[img_id].mtdofs) ;	mtdlen = READ32_BE(pheader.img[img_id].len);	fname = pheader.img[img_id].filename;	if ((mtdofs + mtdlen) > ptable[pt_id].size ) {		fprintf(stderr, "Image too large to fit into the mtd device %s\n", device);		exit(-1);	}		if (!quiet) {		fprintf(stderr, "Writing %s to %s at offset 0x%08X with length %d", fname, device, mtdofs, mtdlen);		fprintf(stderr, " [ ]");    }	fd = my_mtd_open(device, O_RDWR|O_SYNC);	if (fd < 0) {		fprintf(stderr, "Could not open mtd device: %s\n", device);		exit(-1);	}	if (ioctl(fd, MEMGETINFO, &mtdInfo)) {		fprintf(stderr, "Could not get MTD device info from %s\n", device);		close(fd);		exit(-1);	}		lseek(fd, mtdofs, 0);    lseek(imgfd, offset, 0);		rd = 0;	wr = er = mtdofs ;    rn = (mtdlen > sizeof(buf))? sizeof(buf):mtdlen;	while (mtdlen>0) {		if ((rd = read(imgfd, buf, rn)) != rn) {			fprintf(stderr, "Failed reading packed file.\n");			exit(-1);		}		wr += rd ;		/* need to erase the next block before writing data to it */		while (wr > er) {			mtdEraseInfo.start = er ;			mtdEraseInfo.length = mtdInfo.erasesize;			if (!quiet)				fprintf(stderr, "\b\b\b[e]");			/* erase the chunk */			if (ioctl (fd, MEMERASE, &mtdEraseInfo) < 0) {				fprintf(stderr, "Erasing mtd device failed: %s\n", device);				exit(1);			}			er += mtdInfo.erasesize;		}		if (!quiet)			fprintf(stderr, "\b\b\b[w]");		if ((res = write(fd, buf, rn)) != rn) {			if (res < 0)				fprintf(stderr, "Error writing mtd device %s\n", device);			else				fprintf(stderr, "Insufficient space to write mtd device %s\n", device);			exit(-1);		}		mtdlen -= rn;		rn = (mtdlen > sizeof(buf))? sizeof(buf):mtdlen;	}	if (!quiet)		fprintf(stderr, "\b\b\b\b\n");	close(fd);	return 0;}/****************************************/int init_ptable(void){	FILE *fp;	int ret ;	int i, n = 0;	char line[PATH_MAX];	char devfile[PATH_MAX];	char *p ;	uint32_t kk, qq;	char name[30]; 	char dev[30];

⌨️ 快捷键说明

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