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

📄 netflash.c

📁 通过网络刷新flash的工具源代码.linux下使用的
💻 C
📖 第 1 页 / 共 4 页
字号:
		pid = atoi(value);		if (pid)			kill(pid, signo);        unlink(file);    }    fclose(f);}/****************************************************************************//* *	Find the current console device. We output trace to this device *	if it is the controlling tty at process start. */char	*consolelist[] = {	"/dev/console",	"/dev/ttyS0",	"/dev/cua0",	"/dev/ttyS1",	"/dev/cua1",	"/dev/ttyAM0"};#define	clistsize	(sizeof(consolelist) / sizeof(char *)) char *getconsole(void){	struct stat	myst, st;	int		i;	if (fstat(0, &myst) < 0)		return((char *) NULL);	for (i = 0; (i < clistsize); i++) {		if (!stat(consolelist[i], &st) && 				(myst.st_rdev == st.st_rdev))			return(consolelist[i]);	}	return "/dev/null";}/****************************************************************************/static const char *kill_partial[] = {#ifdef CONFIG_USER_SNORT_SNORT	"snort",#endif#ifdef CONFIG_USER_SQUID_SQUID	"squid",#endif#if defined(CONFIG_USER_FREESWAN) || defined(CONFIG_USER_OPENSWAN)	"pluto",#endif#ifdef CONFIG_USER_CLAMAV_CLAMD	"clamd",#endif	NULL};/* * Kill off processes to reclaim some memory.  Only kills processes * that we know are unnecessary for obtaining the image. */void kill_processes_partial(void){	const char **p;	int count;	notice("killing unnecessary tasks...");	sleep(1);	kill(1, SIGTSTP);		/* Stop init from reforking tasks */	atexit(restartinit);		/* If exit prematurely, restart init */	sync();	/* Ask them nicely. */	count = 0;	for (p = kill_partial; *p; p++)		count += killprocname(*p, SIGTERM);	if (count)		sleep(5);		/* give em a moment... */	/* Time for the no-nonsense approach. */	count = 0;	for (p = kill_partial; *p; p++)		count += killprocname(*p, SIGKILL);	if (count)		sleep(2);		/* give em another moment... */}/* * Kill of processes now to reclaim some memory. Need this now so * we can buffer an entire firmware image... */void kill_processes(char *console){	int ttyfd;	struct termios tio;	DIR *dir;	struct dirent *dp;	char filename[128];	if (console == NULL)		console = getconsole();	ttyfd = open(console, O_RDWR|O_NDELAY|O_NOCTTY);	if (ttyfd >= 0) {		if (tcgetattr(ttyfd, &tio) >= 0) {			tio.c_cflag |= CLOCAL;			tcsetattr(ttyfd, TCSANOW, &tio);		}		close(ttyfd);	}	if (!docgi) {		freopen(console, "w", stdout);		freopen(console, "w", stderr);	}		notice("killing tasks...");	fflush(stdout);	sleep(1);		kill(1, SIGTSTP);		/* Stop init from reforking tasks */	atexit(restartinit);		/* If exit prematurely, restart init */	sync();	signal(SIGTERM,SIG_IGN);	/* Don't kill ourselves... */	setpgrp(); 			/* Don't let our parent kill us */	sleep(1);	signal(SIGHUP, SIG_IGN);	/* Don't die if our parent dies due to					 * a closed controlling terminal */		killprocpid("/var/run/ifmond.pid", SIGKILL);	/*Don't take down network interfaces that use dhcpcd*/	dir = opendir(PID_DIR);	if (dir) {		while ((dp = readdir(dir)) != NULL) {			if (strncmp(dp->d_name, DHCPCD_PID_FILE,						sizeof(DHCPCD_PID_FILE)-1) != 0)				continue;			if (strcmp(dp->d_name + strlen(dp->d_name) - 4,						".pid") != 0)				continue;			snprintf(filename, sizeof(filename), "%s/%s",					PID_DIR, dp->d_name);			killprocpid(filename, SIGKILL);		}		closedir(dir);	}	kill(-1, SIGTERM);		/* Kill everything that'll die */	sleep(5);			/* give em a moment... (it may take a while for, e.g., pppd to shutdown cleanly */	kill(-1, SIGKILL);		/* Really make sure that everything is dead */	sleep(2);			/* give em another moment... */	if (console)		freopen(console, "w", stdout);#if CONFIG_USER_NETFLASH_WATCHDOG	if (watchdog)		watchdog_fd = open("/dev/watchdog", O_WRONLY);#endif}/****************************************************************************/#if defined(CONFIG_USER_MOUNT_UMOUNT) || defined(CONFIG_USER_BUSYBOX_UMOUNT)void umount_all(void){	char *localargv[4];	int localargc;	pid_t pid;	int status;	localargc = 0;	localargv[localargc++] = "umount";	localargv[localargc++] = "-a";	localargv[localargc++] = "-r";	localargv[localargc++] = NULL;	pid = vfork();	if (pid == -1) {		error("vfork() failed %m");		exit_failed(VFORK_FAIL);	} else if (pid == 0) {		execvp("/bin/umount", localargv);		_exit(1);	}	waitpid(pid, &status, 0);}#endif/****************************************************************************/static int get_segment(int rd, char *sgdata, int sgpos, int sgsize){	int sglength;	int sgoffset;	if (offset > sgpos)		sgoffset = offset - sgpos;	else		sgoffset = 0;	/* XXX: preserve case could be optimized to read less */	if (preserve || sgoffset) {		if (lseek(rd, sgpos, SEEK_SET) != sgpos) {			error("lseek(%x) failed\n", sgpos);			exit_failed(BAD_SEG_SEEK);		} else if (read(rd, sgdata, preserve ? sgsize : sgoffset) < 0) {			error("read() failed, pos=%x, errno=%d\n",					sgpos, errno);			exit_failed(BAD_SEG_READ);		}	}	sgpos -= offset - sgoffset;	sgdata += sgoffset;	sgsize -= sgoffset;#ifdef CONFIG_USER_NETFLASH_DECOMPRESS	if (doinflate) {		sglength = decompress(sgdata, sgsize);	} else {#endif		/* Copy the file blocks into the segment buffer */		sglength = 0;		while (fileblocks && (fileblocks->pos < sgpos + sgsize)) {			if (fileblocks->pos + fileblocks->length > sgpos + sgsize)				sglength = sgsize;			else				sglength = fileblocks->pos + fileblocks->length - sgpos;			  			if (fileblocks->pos < sgpos) {				memcpy(sgdata, fileblocks->data + (sgpos - fileblocks->pos),						sglength);			} else {				memcpy(sgdata + (fileblocks->pos - sgpos), fileblocks->data,						sglength - (fileblocks->pos - sgpos));			}			if (fileblocks->pos + fileblocks->length > sgpos + sgsize) {				/* Need to keep fileblocks pointing to this block				 * for the start of the next segment. */				break;			}			/* Modify the global: this is an optimization to save searching			 * through blocks that have been programmed already. */			fileblocks = fileblocks->next;		}#ifdef CONFIG_USER_NETFLASH_DECOMPRESS	}#endif	if (sglength !=0) {		if (preserve)			sglength = sgsize;		sglength += sgoffset;	}	return sglength;}static void check_segment(int rd, char *sgdata, int sgpos, int sglength,		char *check_buf){	if (lseek(rd, sgpos, SEEK_SET) != sgpos) {		error("lseek(%x) failed", sgpos);		exitstatus = BAD_SEG_SEEK;	} else if (read(rd, check_buf, sglength) < 0) {		error("read failed, pos=%x, errno=%d",				sgpos, errno);		exitstatus = BAD_SEG_READ;	} else if (memcmp(sgdata, check_buf, sglength) != 0) {		int i;		error("check failed, pos=%x", sgpos);		for (i = 0; i < sglength; i++) {			if (sgdata[i] != check_buf[i])				printf("%x(%x,%x) ", sgpos + i,						sgdata[i] & 0xff,						check_buf[i] & 0xff);		}		printf("\n");		exitstatus = BAD_SEG_CHECK;	}}#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULES)static void program_mtd_segment(int rd, char *sgdata,		int sgpos, int sglength, int sgsize){	erase_info_t erase_info;	int pos;	/* Unlock the segment to be reprogrammed.  */	if (dounlock) {		erase_info.start = sgpos;		erase_info.length = sgsize;		/* Don't bother checking for failure */		ioctl(rd, MEMUNLOCK, &erase_info);	}	erase_info.start = sgpos;	erase_info.length = sgsize;	if (lseek(rd, sgpos, SEEK_SET) != sgpos) {		error("lseek(%x) failed", sgpos);		exitstatus = BAD_SEG_SEEK;	} else if (ioctl(rd, MEMERASE, &erase_info) < 0) {		error("ioctl(MEMERASE) failed, errno=%d", errno);		exitstatus = ERASE_FAIL;	} else if (sglength > 0) {		if (lseek(rd, sgpos, SEEK_SET) != sgpos) {			error("lseek(%x) failed", sgpos);			exitstatus = BAD_SEG_SEEK;		} else {			/*			 * Always write in 512 byte chunks as MTD on			 * a DoC device can only handle 512 byte writes.			 *			 * NOTE: we rely on the fact the sgdata buffer is always			 *       a multiple of 512 in real size (erase_size for MTD)			 *       which should always be true, I think.			 */			for (pos = sgpos; (sglength >= 512); ) {				if (write(rd, sgdata, 512) == -1) {					error("write() failed, "						"pos=%x, errno=%d",						pos, errno);					exitstatus = BAD_SEG_WRITE;				}				pos += 512;				sgdata += 512;				sglength -= 512;			}			/*			 * If there is a remainder, then still write a 512 byte			 * chunk, but preserve what is already there.			 */			if (sglength > 0) {				char buf[512];				if (lseek(rd, pos, SEEK_SET) != pos) {					error("lseek(%x) failed",						pos);					exitstatus = BAD_SEG_SEEK;				} else if (read(rd, buf, 512) == -1) {					error("read() failed, "						"pos=%x, errno=%d",						pos, errno);					exitstatus = BAD_SEG_READ;				} else if (lseek(rd, pos, SEEK_SET) != pos) {					error("lseek(%x) failed",						pos);					exitstatus = BAD_SEG_SEEK;				} else {					memcpy(buf, sgdata, sglength);					if (write(rd, buf, 512) == -1) {						error("write() failed, pos=%x, errno=%d",							pos, errno);						exitstatus = BAD_SEG_WRITE;					}				}			}		}	} else if (dojffs2) {		static struct jffs2_unknown_node marker = {			JFFS2_MAGIC_BITMASK,			JFFS2_NODETYPE_CLEANMARKER,			sizeof(struct jffs2_unknown_node),#if __BYTE_ORDER == __BIG_ENDIAN			0xf060dc98#else			0xe41eb0b1#endif		};		if (lseek(rd, sgpos, SEEK_SET) != sgpos) {			error("lseek(%x) failed", sgpos);			exitstatus = BAD_SEG_SEEK;		} else if (write(rd, &marker, sizeof(marker)) < 0) {			error("write() failed, pos=%x, "				"errno=%d", sgpos, errno);			exitstatus = BAD_SEG_WRITE;		}	}	if (dolock) {		erase_info.start = sgpos;		erase_info.length = sgsize;		if (ioctl(rd, MEMLOCK, &erase_info) < 0) {			error("ioctl(MEMLOCK) failed, "				"errno=%d", errno);			exitstatus = ERASE_FAIL;		}	}}#elsestatic void program_blkmem_segment(int rd, char *sgdata, int sgpos,	int sglength, int sgsize){	char buf[128];	struct blkmem_program_t *prog = (struct blkmem_program_t *)buf;	prog->magic1 = BMPROGRAM_MAGIC_1;	prog->magic2 = BMPROGRAM_MAGIC_2;	prog->reset = 0;	prog->blocks = 1;	prog->block[0].data = sgdata;	prog->block[0].pos = sgpos;	prog->block[0].length = sglength;	prog->block[0].magic3 = BMPROGRAM_MAGIC_3;	if (ioctl(rd, BMPROGRAM, prog) != 0) {		error("ioctl(BMPROGRAM) failed, errno=%d", errno);		exitstatus = BAD_SEG_WRITE;	}}#endif#if defined(CONFIG_NFTL_RW) || defined(CONFIG_IDE)static void program_generic_segment(int rd, char *sgdata,		int sgpos, int sglength, int sgsize){	if (!stop_early && sglength < sgsize) {		memset(sgdata + sglength, 0xff, sgsize - sglength);		sglength = sgsize;	}	if (sglength > 0) {		if (lseek(rd, sgpos, SEEK_SET) != sgpos) {			error("lseek(%x) failed", sgpos);			exitstatus = BAD_SEG_SEEK;		} else if (write(rd, sgdata, sglength) < 0) {			error("write() failed, pos=%x, "					"errno=%d", sgpos, errno);			exitstatus = BAD_SEG_WRITE;		} else if (fdatasync(rd) < 0) {			error("fdatasync() failed, pos=%x, "					"errno=%d", sgpos, errno);			exitstatus = BAD_SEG_CHECK;		}	}}#endifstatic void program_flash(int rd, int devsize, char *sgdata, int sgsize,		char *check_buf){	int sgpos, sglength;	unsigned long total;#ifdef CONFIG_LEDMAN	int ledmancount = 0;#endif#ifdef CONFIG_LEDMAN	ledman_cmd(LEDMAN_CMD_ALT_ON, LEDMAN_NVRAM_1);	ledman_cmd(LEDMAN_CMD_ALT_ON, LEDMAN_NVRAM_2);#endif	/* Round the image size up to the segment size */	if (stop_early) {		total = (image_length + sgsize - 1) & ~(sgsize - 1);	}	else {		total = devsize;	}	/* Write the data one segment at a time */	sgpos = offset - (offset % sgsize);	for (; sgpos < devsize; sgpos += sgsize) {		sglength = get_segment(rd, sgdata, sgpos, sgsize);		if (stop_early && sglength <= 0) {			break;		}		if (checkimage) {			check_segment(rd, sgdata, sgpos, sglength, check_buf);		}		else#if defined(CONFIG_MTD_NETtel)		if (!preserveconfig || sgpos < 0xe0000 || sgpos >= 0x100000) {#endif			program_segment(rd, sgdata, sgpos, sglength, sgsize);#ifdef CONFIG_LEDMAN			ledman_cmd(LEDMAN_CMD_OFF | LEDMAN_CMD_ALTBIT,					ledmancount ? LEDMAN_NVRAM_1 : LEDMAN_NVRAM_2);			ledman_cmd(LEDMAN_CMD_ON | LEDMAN_CMD_ALTBIT,					ledmancount ? LEDMAN_NVRAM_2 : LEDMAN_NVRAM_1);			ledmancount = (ledmancount + 1) & 1;#endif#ifdef CONFIG_USER_NETFLASH_WATCHDOG			if (watchdog)				write(watchdog_fd, "\0", 1); #endif#if defined(CONFIG_MTD_NETtel)		} /* if (!preserveconfig || ...) */#endif		printf("\r%5dK %3d%%", (sgpos + sgsize) / 1024, (sgpos + sgsize) * 100L / total);		fflush(stdout);	}	printf("\n"); fflush(stdout);#ifdef CONFIG_LEDMAN	ledman_cmd(LEDMAN_CMD_ALT_OFF, LEDMAN_NVRAM_1);	ledman_cmd(LEDMAN_CMD_ALT_OFF, LEDMAN_NVRAM_2);#endif	/* Put the flash back in read mode, some old boot loaders don't */	lseek(rd, 0, SEEK_SET);	read(rd, sgdata, 1);}/****************************************************************************/int usage(int rc){  printf("usage: netflash [-bCfFhijklntuv"#ifdef CONFIG_USER_NETFLASH_DECOMPRESS	"z"#endif	"?] [-c console-device] [-d delay] "#ifdef CONFIG_USER_NETFLASH_SETSRC	"[-I ip-address] "#endif#ifdef CONFIG_USER_NETFLASH_HMACMD5	"[-m hmac-md5-key] "#endif	"[-o offset] [-r flash-device] "	"[net-server] file-name\n\n"	"\t-b\tdon't reboot hardware when done\n"	"\t-C\tcheck that image was written correctly\n"	"\t-f\tuse FTP as load protocol\n"	"\t-F\tforce overwrite (do not preserve special regions)\n"  	"\t-h\tprint help\n"	"\t-i\tignore any version information\n"	"\t-H\tignore hardware type information\n"#ifdef CONFIG_USER_NETFLASH_SETSRC	"\t-I\toriginate TFTP request from this address\n"#endif	"\t-j\timage is a JFFS2 filesystem\n"	"\t-k\tdon't kill other processes (or delays kill until\n"	"\t\tafter downloading when root filesystem is inside flash)\n"	"\t-K\tonly kill unnecessary processes (or delays kill until\n"	"\t\tafter downloading when root filesystem is inside flash)\n"	"\t-l\tlock flash segments when done\n"  	"\t-n\tfile with no checksum at end (implies no version information)\n"	"\t-p\tpreserve portions of flash segments not actually written.\n"  	"\t-s\tstop erasing/programming at end of input data\n"  	"\t-S\tdo not stop erasing/programming at end of input data\n"	"\t-t\tcheck the image and then throw it away \n"	"\t-u\tunlock flash segments before programming\n"  	"\t-v\tdisplay version number\n"#if CONFIG_USER_NETFLASH_WATCHDOG  	"\t-w\tdon't tickle hardware watchdog\n"#endif#ifdef CONFIG_USER_NETFLASH_DECOMPRESS	"\t-z\tdecompress image before writing\n"#endif  );  exit(rc);}/****************************************************************************//* * when we call reboot,  we don't want anything in our way, most certainly * not logd ! */#define __NR_raw_reboot __NR_rebootstatic _syscall3(int, raw_reboot, int, magic, int, magic2, int, flag);/****************************************************************************/int netflashmain(int argc, char *argv[]){	char *srvname, *filename;	char *rdev, *console;	char *sgdata, *check_buf = NULL;

⌨️ 快捷键说明

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