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

📄 tfs.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 5 页
字号:

	/* Info field...
	 */
	if (info) {
		if (strcmp(info,TFS_INFO(tfp)))
			return(-1);
	}
	else {
		if (TFS_INFO(tfp)[0] != 0)
			return(-1);
	}

	/* Flags...
	 */
	if (tfsflagsatob(flags, &bflags) == -1)
		return(-1);
	if (bflags != (TFS_FLAGS(tfp) & 0x7ff))
		return(-1);
	
	/* Data...
	 */
	if (memcmp(TFS_BASE(tfp),(char *)src,size)) 
		return(-1);

	return(0);
}

/* tfsinit():
 *	Clear out all the flash that is dedicated to the file system.
 *	This removes all currently stored files and erases the flash.
 *	MONLIB NOTICE: this function is accessible through monlib.c.
 */
int
_tfsinit(TDEV *tdpin)
{
	int		ret;
	TDEV *tdp;

	/* Step through the table of TFS devices and erase each sector...
	 */
	for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
		if (!tdpin || (tdp == tdpin)) {
			ret = tfsflasheraseall(tdp);
			if (ret != TFS_OKAY)
				return(ret);
		}
	}
	return(TFS_OKAY);
}

int
tfsinit(void)
{
	if (tfsTrace > 0)
		printf("tfsinit()\n");
	return(_tfsinit(0));
}


/* tfsSpaceErased():
 *	Return 0 if the space pointed to by the incoming arguments is not
 *	erased; else 1.
 */
int
tfsSpaceErased(uchar *begin,int size)
{
	uchar	*end;

	end = begin+size;

	while(begin < end) {
		if (*begin != 0xff)
			return(0);
		begin++;
	}
	return(1);
}

/* tfsFtot():
 *	Return the number of files in a device, or all devices if tdpin is null.
 */
int
tfsFtot(TDEV *tdpin)
{
	int		ftot;
	TFILE	*fp;
	TDEV	*tdp;

	ftot = 0;
	for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
		if (!tdpin || (tdpin == tdp)) {
			fp = (TFILE *)tdp->start;
			while (fp->hdrsize != ERASED16) {
				ftot++;
				fp = nextfp(fp,tdp);
			}
		}
	}
	return(ftot);
}

/* tfsFileIsOpened():
 *	Return 1 if file is currently opened; else 0.
 */
int
tfsFileIsOpened(char *name)
{
	int	 i;
	struct	tfsdat *slot;

	slot = tfsSlots;
	for (i=0;i<TFS_MAXOPEN;i++,slot++) {
		if ((slot->offset >= 0) && !strcmp(slot->hdr.name,name))
			return(1);
	}
	return(0);
}

/* tfsunopen():
 *	If the incoming file descriptor is valid, mark that file as no-longer
 *	opened and return TFS_OKAY; else return TFSERR_BADARG.
 *	descriptor.
 */
static long
tfsunopen(int fd)
{
	if ((fd < 0) || (fd >= TFS_MAXOPEN))
		return(TFSERR_BADARG);
	if (tfsSlots[fd].offset == -1)
		return(TFSERR_BADARG);
	tfsSlots[fd].offset = -1;
	return(TFS_OKAY);
}

/* tfsctrl():
 *	Provides an ioctl-like interface to tfs.
 *	Requests supported:
 *		TFS_ERRMSG:		Return error message (char *) corresponding to
 *						the incoming error number (arg1).
 *		TFS_MEMUSE:		Return the total amount of memory currently in use by
 *						TFS.
 *		TFS_MEMAVAIL:	Return the amount of memory currently avaialable for
 *						use in TFS.
 *		TFS_MEMDEAD:	Return the amount of memory currently in use by
 *						dead files in TFS.
 *		TFS_DEFRAG:		Mechanism for the application to issue
 *						a defragmentation request.
 *						Arg1: if 1, then reset after defrag is complete.
 *						Arg2: verbosity level.
 *		TFS_TELL:		Return the offset into the file specified by the
 *						incoming file descriptor (arg1).
 *		TFS_FATOB:		Return the binary equivalent of the TFS flags string
 *						pointed to by arg1.
 *		TFS_FBTOA:		Return the string equivalent of the TFS flags (long)
 *						in arg1, destination buffer in arg2.
 *		TFS_UNOPEN:		In TFS, a the data is not actually written to FLASH
 *						until the tfsclose() function is called.  This argument
 *						to tfsctrl() allows a file to be opened and possibly
 *						written to, then unopened without actually modifying
 *						the FLASH.  The value of arg1 file descriptor to 
 *						apply the "unopen" to.
 *		TFS_TIMEFUNCS:	This ctrl call is used to tell TFS what function
 *						to call for time information...
 *						Arg1 is a pointer to:
 *							(long)getLtime(void)
 *							- Get Long Time...
 *							Returns a long representation of time.
 *						Arg2 is a pointer to:
 *							(char *)getAtime(long tval,char *buf).
 *							- Get Ascii Time...
 *							If tval is zero, the buf is loaded with a string
 *							representing the current time;
 *							If tval is non-zero, then buf is loaded with a
 *							string conversion of the value of tval.
 *						Note that since it is up to these functions to 
 *						make the conversion between binary version of time
 *						and ascii version, we don't define the exact meaning
 *						of the value returne by getBtime().
 *		TFS_DOCOMMAND:	Allows the application to redefine the function
 *						that is called to process each line of a script.
 *						This is useful if the application has its own
 *						command interpreter, but wants to use the scripting
 *						facilities of the monitor.
 *						Arg1 is a pointer to the docommand function to be
 *						used instead of the standard;
 *						Arg2 is a pointer to a location into which the current
 *						docommand function pointer can be stored.
 *						If arg1 is 0, load standard docommand;
 *						if arg2 is 0, don't load old value.
 *		TFS_INITDEV:	Allows the application to initialize one of TFS's
 *						devices.  Arg1 is a pointer to the device name prefix.
 *		TFS_DEFRAGDEV:	Allows the application to defrag one of TFS's
 *						devices.  Arg1 is a pointer to the device name prefix.
 *		TFS_CHECKDEV:	Allows the application to check one of TFS's
 *						devices.  Arg1 is a pointer to the device name prefix.
 *		TFS_RAMDEV:  	Allows the application to create (or remove) a
 *						special temporary TFS device in RAM.
 *
 *
 *	MONLIB NOTICE: this function is accessible through monlib.c.
 */

long
tfsctrl(int rqst,long arg1,long arg2)
{
	long	retval, flag;
	TDEV	*tdp;
	TINFO	tinfo;
	TRAMDEV	*trdp;

	if (tfsTrace > 0)
		printf("tfsctrl(%d,0x%lx,0x%lx)\n",rqst,arg1,arg2);

	switch(rqst) {
		case TFS_ERRMSG:
			retval = (long)tfserrmsg(arg1);
			break;
		case TFS_MEMUSE:
			tfsmemuse(0,&tinfo,0);
			retval = tinfo.memused;
			break;
		case TFS_MEMAVAIL:
			tfsmemuse(0,&tinfo,0);
			retval = tinfo.memfordata;
			break;
		case TFS_MEMDEAD:
			tfsmemuse(0,&tinfo,0);
			retval = tinfo.deadovrhd+tinfo.deaddata;
			break;
		case TFS_INITDEV:
			tdp = gettfsdev_fromprefix((char *)arg1,0);
			if (!tdp)
				retval = TFSERR_BADARG;
			else
				retval = _tfsinit(tdp);
			break;
		case TFS_CHECKDEV:
			tdp = gettfsdev_fromprefix((char *)arg1,0);
			if (!tdp)
				retval = TFSERR_BADARG;
			else
				retval = tfscheck(tdp,0);
			break;
		case TFS_DEFRAGDEV:
			tdp = gettfsdev_fromprefix((char *)arg1,0);
			if (!tdp)
				retval = TFSERR_BADARG;
			else
				retval = tfsclean(tdp,0);
			break;
		case TFS_DEFRAG:
			for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) 
				tfsclean(tdp,(int)arg1);
			retval = 0;
			break;
		case TFS_FCOUNT:
			if (arg1) {
				tdp = gettfsdev_fromprefix((char *)arg1,0);
				if (!tdp)
					retval = TFSERR_BADARG;
				else
					retval = tfsftot(tdp);
			}
			else {
				retval = tfsftot(0);
			}
			break;
		case TFS_DEFRAGON:
			retval = tfsclean_on();
			break;
		case TFS_DEFRAGOFF:
			retval = tfsclean_off();
			break;
		case TFS_UNOPEN:
			retval = tfsunopen((int)arg1);
			break;
		case TFS_FATOB:
			retval = tfsflagsatob((char *)arg1,&flag);
			if (retval == TFS_OKAY)
				retval = flag;
			break;
		case TFS_FBTOA:
			retval = (long)tfsflagsbtoa(arg1,(char *)arg2);
			if (retval == 0)
				retval = TFSERR_BADARG;
			break;
		case TFS_HEADROOM:
			retval = tfsheadroom(arg1);
			break;
		case TFS_RAMDEV:
			trdp = (TRAMDEV *)arg1;
			retval = tfsramdevice(trdp->name,trdp->base,trdp->size);
			break;
		case TFS_TELL:
			retval = tfstell(arg1);
			break;
		case TFS_TIMEFUNCS:
			tfsGetLtime = (long(*)(void))arg1;
			tfsGetAtime = (char *(*)(long,char *,int))arg2;
			retval = TFS_OKAY;
			break;
		case TFS_DOCOMMAND:
			if (arg2)
				*(long *)arg2 = (long)tfsDocommand;
			if (arg1)
				tfsDocommand = (int(*)(char *,int))arg1;
			else
				tfsDocommand = docommand;
			retval = TFS_OKAY;
			break;
		default:
			retval = TFSERR_BADARG;
			break;
	}
	return(retval);
}

/* tfsNameToDevice():
 * Given the filename, return the device pointer associated with
 * that filename.  The device used depends on the prefix of
 * the incoming file name.  If the incoming prefix doesn't match
 * any of the devices in the table, then return a pointer to the
 * first device in the table (assumed to be the default).
 */
TDEV *
tfsNameToDevice(char *name)
{
	TDEV *tdp;

	for(tdp=tfsDeviceTbl;tdp->start != TFSEOT;tdp++) {
		if (!strncmp(name,tdp->prefix,strlen(tdp->prefix)))
			break;
	}
	if (tdp->start == TFSEOT)
		tdp = tfsDeviceTbl;

	return(tdp);
}

/* tfsramdevice():
 * Create (or remove) a temporary (RAM-based) TFS device..
 * This function is callable from both the API and the CLI.
 * The TFS device table is established with one extra slot.
 * The purpose of that slot is to allow the user to establish
 * a temporary, ram-based TFS device.  This function supports
 * that capability.
 */
int
tfsramdevice(char *name,long base,long size)
{
	TDEV	*tdp;
	int		ramdevexists = 0;
	char	tmpname[TFSNAMESIZE+1];
	static	char devname[TFSNAMESIZE+1];
	
	snprintf(tmpname,TFSNAMESIZE,"//Flash_Block_%s/",name);

	if (tfsTrace > 0) 
		printf("tfsramdevice(%s,0x%lx,%ld)\n",name,base,size);

	/* Scan through the device table to find the slot that can
 	 * be used by the "ramdev" device...
	 */
	tdp = tfsDeviceTbl;
	while(tdp->start != TFSEOT) {
		if (strcmp(tdp->prefix,tmpname) == 0) {
			ramdevexists = 1;
			if (size != 0) 
				return(TFSERR_FILEEXISTS);
		}
		tdp++;
	}

	if (size == 0) {
		if (ramdevexists) {
			memset((char *)tdp->start,0,tdp->end-tdp->start);
			tdp->start = 0;
			tdp->devinfo = 0;
			tdp->end = 0;
			tdp--;
			tdp->start = TFSEOT;
			devname[0] = 0;
		}
		else
			return(TFSERR_NOFILE);
	}
	else {
		if (devname[0] != 0)
			return(TFSERR_FILEEXISTS);

		strcpy(devname,tmpname);
		tdp->prefix = devname;
		tdp->start = base;
		tdp->sparesize = 0;
		tdp->sectorcount = 0;
		tdp->devinfo = TFS_DEVTYPE_RAM;
		tdp->end = tdp->start + size - 1;
		tdp->spare = 0;
		memset((char *)tdp->start,0xff,size);;
		tdp++;
		tdp->start = TFSEOT;
	}
	return(TFS_OKAY);
}

/* tfsadd():
 *	Add a file to the current list.
 *	If the file already exists AND everything is identical between the
 *	old and the new (flags, info and data), then return and do nothing;
 *	else remove the old file prior to adding the new one.
 *
 *	Note:
 *	At the point when tfsadd is called for a file that currently exists,
 *	the old file must be removed and a new one is put in its place.  This
 *	opens up the possibility of losing the file if a power-hit or reset was
 *	to occur between the point at which the old file was removed and the new
 *	one was put in its place.  To overcome this problem, TFS files have a
 *	flag called TFS_NSTALE.  It is a bit that is normally 1, but cleared
 *	if it becomes stale (hence the name TFS_NSTALE).  A file is
 *	in this mode only for a short time... the time it takes to write the
 *	new file that replaces the file that was made stale.
 *	Now, if a reset occurs after the file is stale, depending on 
 *	whether or not the new file was written, it will either be removed or
 *	used to recreate the original file because the write of the new file
 *	was chopped off by the power hit.  Refer to the function tfsstalecheck()
 *	for details on the recovery after a reset or powerhit.
 *	MONLIB NOTICE: this function is accessible through monlib.c.
 */
int
tfsadd(char *name, char *info, char *flags, uchar *src, int size)
{
	TDEV	*tdp;
	TFILE	*fp, tf, *sfp;
	long	bflags;
	ulong	endoftfsflash, nextfileaddr, thisfileaddr;
	ulong	crc_pass1, crc_pass2, state_table_overhead;
	int		ftot, cleanupcount, err, stale, ssize, rc;

	if (!info) info = "";
	if (!flags) flags = "";

	if (tfsTrace > 0)
		printf("tfsadd(%s,%s,%s,0x%lx,%d)\n", name,info,flags,(ulong)src,size);

	/* Check for valid size and name:
	 */
	if ((size < 0) || (!name) || (*name == 0))
		return(TFSERR_BADARG);

	/* If name or info field length is too long, abort now...
	 */
	if ((strlen(name) > TFSNAMESIZE) ||
		((info) && (strlen(info) > TFSINFOSIZE)))
		return(TFSERR_NAMETOOBIG);

⌨️ 快捷键说明

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