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

📄 fw_env.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
📖 第 1 页 / 共 2 页
字号:
{	int fd, fdr, rc, otherdev, len, resid;	erase_info_t erase;	char *data;	if ((fd = open (DEVNAME (curdev), mode)) < 0) {		fprintf (stderr,			"Can't open %s: %s\n",			DEVNAME (curdev), strerror (errno));		return (-1);	}	len = sizeof (environment.crc);	if (HaveRedundEnv) {		len += sizeof (environment.flags);	}	if (mode == O_RDWR) {		if (HaveRedundEnv) {			/* switch to next partition for writing */			otherdev = !curdev;			if ((fdr = open (DEVNAME (otherdev), mode)) < 0) {				fprintf (stderr,					"Can't open %s: %s\n",					DEVNAME (otherdev),					strerror (errno));				return (-1);			}		} else {			otherdev = curdev;			fdr = fd;		}		printf ("Unlocking flash...\n");		erase.length = DEVESIZE (otherdev);		erase.start = DEVOFFSET (otherdev);		ioctl (fdr, MEMUNLOCK, &erase);		if (HaveRedundEnv) {			erase.length = DEVESIZE (curdev);			erase.start = DEVOFFSET (curdev);			ioctl (fd, MEMUNLOCK, &erase);			environment.flags = active_flag;		}		printf ("Done\n");		resid = DEVESIZE (otherdev) - CFG_ENV_SIZE;		if (resid) {			if ((data = malloc (resid)) == NULL) {				fprintf (stderr,					"Cannot malloc %d bytes: %s\n",					resid,					strerror (errno));				return (-1);			}			if (lseek (fdr, DEVOFFSET (otherdev) + CFG_ENV_SIZE, SEEK_SET)				== -1) {				fprintf (stderr, "seek error on %s: %s\n",					DEVNAME (otherdev),					strerror (errno));				return (-1);			}			if ((rc = read (fdr, data, resid)) != resid) {				fprintf (stderr,					"read error on %s: %s\n",					DEVNAME (otherdev),					strerror (errno));				return (-1);			}		}		printf ("Erasing old environment...\n");		erase.length = DEVESIZE (otherdev);		erase.start = DEVOFFSET (otherdev);		if (ioctl (fdr, MEMERASE, &erase) != 0) {			fprintf (stderr, "MTD erase error on %s: %s\n",				DEVNAME (otherdev),				strerror (errno));			return (-1);		}		printf ("Done\n");		printf ("Writing environment to %s...\n", DEVNAME (otherdev));		if (lseek (fdr, DEVOFFSET (otherdev), SEEK_SET) == -1) {			fprintf (stderr,				"seek error on %s: %s\n",				DEVNAME (otherdev), strerror (errno));			return (-1);		}		if (write (fdr, &environment, len) != len) {			fprintf (stderr,				"CRC write error on %s: %s\n",				DEVNAME (otherdev), strerror (errno));			return (-1);		}		if (write (fdr, environment.data, ENV_SIZE) != ENV_SIZE) {			fprintf (stderr,				"Write error on %s: %s\n",				DEVNAME (otherdev), strerror (errno));			return (-1);		}		if (resid) {			if (write (fdr, data, resid) != resid) {				fprintf (stderr,					"write error on %s: %s\n",					DEVNAME (curdev), strerror (errno));				return (-1);			}			free (data);		}		if (HaveRedundEnv) {			/* change flag on current active env partition */			if (lseek (fd, DEVOFFSET (curdev) + sizeof (ulong), SEEK_SET)				== -1) {				fprintf (stderr, "seek error on %s: %s\n",					DEVNAME (curdev), strerror (errno));				return (-1);			}			if (write (fd, &obsolete_flag, sizeof (obsolete_flag)) !=				sizeof (obsolete_flag)) {				fprintf (stderr,					"Write error on %s: %s\n",					DEVNAME (curdev), strerror (errno));				return (-1);			}		}		printf ("Done\n");		printf ("Locking ...\n");		erase.length = DEVESIZE (otherdev);		erase.start = DEVOFFSET (otherdev);		ioctl (fdr, MEMLOCK, &erase);		if (HaveRedundEnv) {			erase.length = DEVESIZE (curdev);			erase.start = DEVOFFSET (curdev);			ioctl (fd, MEMLOCK, &erase);			if (close (fdr)) {				fprintf (stderr,					"I/O error on %s: %s\n",					DEVNAME (otherdev),					strerror (errno));				return (-1);			}		}		printf ("Done\n");	} else {		if (lseek (fd, DEVOFFSET (curdev), SEEK_SET) == -1) {			fprintf (stderr,				"seek error on %s: %s\n",				DEVNAME (curdev), strerror (errno));			return (-1);		}		if (read (fd, &environment, len) != len) {			fprintf (stderr,				"CRC read error on %s: %s\n",				DEVNAME (curdev), strerror (errno));			return (-1);		}		if ((rc = read (fd, environment.data, ENV_SIZE)) != ENV_SIZE) {			fprintf (stderr,				"Read error on %s: %s\n",				DEVNAME (curdev), strerror (errno));			return (-1);		}	}	if (close (fd)) {		fprintf (stderr,			"I/O error on %s: %s\n",			DEVNAME (curdev), strerror (errno));		return (-1);	}	/* everything ok */	return (0);}/* * s1 is either a simple 'name', or a 'name=value' pair. * s2 is a 'name=value' pair. * If the names match, return the value of s2, else NULL. */static uchar *envmatch (uchar * s1, uchar * s2){	while (*s1 == *s2++)		if (*s1++ == '=')			return (s2);	if (*s1 == '\0' && *(s2 - 1) == '=')		return (s2);	return (NULL);}/* * Prevent confusion if running from erased flash memory */static int env_init (void){	int crc1, crc1_ok;	uchar *addr1;	int crc2, crc2_ok;	uchar flag1, flag2, *addr2;	if (parse_config ())		/* should fill envdevices */		return 1;	if ((addr1 = calloc (1, ENV_SIZE)) == NULL) {		fprintf (stderr,			"Not enough memory for environment (%ld bytes)\n",			ENV_SIZE);		return (errno);	}	/* read environment from FLASH to local buffer */	environment.data = addr1;	curdev = 0;	if (flash_io (O_RDONLY)) {		return (errno);	}	crc1_ok = ((crc1 = crc32 (0, environment.data, ENV_SIZE))			   == environment.crc);	if (!HaveRedundEnv) {		if (!crc1_ok) {			fprintf (stderr,				"Warning: Bad CRC, using default environment\n");			environment.data = default_environment;			free (addr1);		}	} else {		flag1 = environment.flags;		curdev = 1;		if ((addr2 = calloc (1, ENV_SIZE)) == NULL) {			fprintf (stderr,				"Not enough memory for environment (%ld bytes)\n",				ENV_SIZE);			return (errno);		}		environment.data = addr2;		if (flash_io (O_RDONLY)) {			return (errno);		}		crc2_ok = ((crc2 = crc32 (0, environment.data, ENV_SIZE))				   == environment.crc);		flag2 = environment.flags;		if (crc1_ok && !crc2_ok) {			environment.data = addr1;			environment.flags = flag1;			environment.crc = crc1;			curdev = 0;			free (addr2);		} else if (!crc1_ok && crc2_ok) {			environment.data = addr2;			environment.flags = flag2;			environment.crc = crc2;			curdev = 1;			free (addr1);		} else if (!crc1_ok && !crc2_ok) {			fprintf (stderr,				"Warning: Bad CRC, using default environment\n");			environment.data = default_environment;			curdev = 0;			free (addr2);			free (addr1);		} else if (flag1 == active_flag && flag2 == obsolete_flag) {			environment.data = addr1;			environment.flags = flag1;			environment.crc = crc1;			curdev = 0;			free (addr2);		} else if (flag1 == obsolete_flag && flag2 == active_flag) {			environment.data = addr2;			environment.flags = flag2;			environment.crc = crc2;			curdev = 1;			free (addr1);		} else if (flag1 == flag2) {			environment.data = addr1;			environment.flags = flag1;			environment.crc = crc1;			curdev = 0;			free (addr2);		} else if (flag1 == 0xFF) {			environment.data = addr1;			environment.flags = flag1;			environment.crc = crc1;			curdev = 0;			free (addr2);		} else if (flag2 == 0xFF) {			environment.data = addr2;			environment.flags = flag2;			environment.crc = crc2;			curdev = 1;			free (addr1);		}	}	return (0);}static int parse_config (){	struct stat st;#if defined(CONFIG_FILE)	/* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */	if (get_config (CONFIG_FILE)) {		fprintf (stderr,			"Cannot parse config file: %s\n", strerror (errno));		return 1;	}#else	strcpy (DEVNAME (0), DEVICE1_NAME);	DEVOFFSET (0) = DEVICE1_OFFSET;	ENVSIZE (0) = ENV1_SIZE;	DEVESIZE (0) = DEVICE1_ESIZE;#ifdef HAVE_REDUND	strcpy (DEVNAME (1), DEVICE2_NAME);	DEVOFFSET (1) = DEVICE2_OFFSET;	ENVSIZE (1) = ENV2_SIZE;	DEVESIZE (1) = DEVICE2_ESIZE;	HaveRedundEnv = 1;#endif#endif	if (stat (DEVNAME (0), &st)) {		fprintf (stderr,			"Cannot access MTD device %s: %s\n",			DEVNAME (0), strerror (errno));		return 1;	}	if (HaveRedundEnv && stat (DEVNAME (1), &st)) {		fprintf (stderr,			"Cannot access MTD device %s: %s\n",			DEVNAME (2), strerror (errno));		return 1;	}	return 0;}#if defined(CONFIG_FILE)static int get_config (char *fname){	FILE *fp;	int i = 0;	int rc;	char dump[128];	if ((fp = fopen (fname, "r")) == NULL) {		return 1;	}	while ((i < 2) && ((rc = fscanf (fp, "%s %lx %lx %lx",				  DEVNAME (i),				  &DEVOFFSET (i),				  &ENVSIZE (i),				  &DEVESIZE (i)  )) != EOF)) {		/* Skip incomplete conversions and comment strings */		if ((rc < 3) || (*DEVNAME (i) == '#')) {			fgets (dump, sizeof (dump), fp);	/* Consume till end */			continue;		}		i++;	}	fclose (fp);	HaveRedundEnv = i - 1;	if (!i) {			/* No valid entries found */		errno = EINVAL;		return 1;	} else		return 0;}#endif

⌨️ 快捷键说明

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