Пример #1
0
/* _tfsclean():
 *	This is an alternative to the complicated defragmentation above.
 *	It simply scans through the file list and copies all valid files
 *	to RAM; then flash is erased and the RAM is copied back to flash.
 *  <<< WARNING >>>
 *  THIS FUNCTION SHOULD NOT BE INTERRUPTED AND IT WILL BLOW AWAY
 *  ANY APPLICATION CURRENTLY IN CLIENT RAM SPACE.
 */
int
_tfsclean(TDEV *tdp, int notused, int verbose)
{
	TFILE	*tfp;
	uchar	*tbuf;
	ulong	appramstart;
	int		dtot, nfadd, len, err, chkstat;

	if (TfsCleanEnable < 0)
		return(TFSERR_CLEANOFF);

	appramstart = getAppRamStart();

	/* Determine how many "dead" files exist. */
	dtot = 0;
	tfp = (TFILE *)tdp->start;
	while(validtfshdr(tfp)) {
		if (!TFS_FILEEXISTS(tfp))
			dtot++;
		tfp = nextfp(tfp,tdp);
	}

	if (dtot == 0)
		return(TFS_OKAY);

	printf("Reconstructing device %s with %d dead file%s removed...\n",
		tdp->prefix, dtot,dtot>1 ? "s":"");

	tbuf = (char *)appramstart;
	tfp = (TFILE *)(tdp->start);
	nfadd = tdp->start;
	while(validtfshdr(tfp)) {
		if (TFS_FILEEXISTS(tfp)) {
			len = TFS_SIZE(tfp) + sizeof(struct tfshdr);
			if (len % TFS_FSIZEMOD)
				len += TFS_FSIZEMOD - (len % TFS_FSIZEMOD);
			nfadd += len;
			if (s_memcpy(tbuf,(uchar *)tfp,len,0,0) != 0)
				return(TFSERR_MEMFAIL);
			
			((struct tfshdr *)tbuf)->next = (struct tfshdr *)nfadd;
			tbuf += len;
		}
		tfp = nextfp(tfp,tdp);
	}

	/* Erase the flash device: */
	err = _tfsinit(tdp);
	if (err != TFS_OKAY)
		return(err);

	/* Copy data placed in RAM back to flash: */
	err = AppFlashWrite((ulong *)(tdp->start),(ulong *)appramstart,
		(tbuf-(uchar*)appramstart));
	if (err < 0)
		return(TFSERR_FLASHFAILURE);

	/* All defragmentation is done, so verify sanity of files... */
	chkstat = tfscheck(tdp,verbose);

	return(chkstat);
}
Пример #2
0
/* _tfsclean():
 *	This is an alternative to the complicated defragmentation above.
 *	It simply scans through the file list and copies all valid files
 *	to RAM; then flash is erased and the RAM is copied back to flash.
 *  <<< WARNING >>>
 *  THIS FUNCTION SHOULD NOT BE INTERRUPTED AND IT WILL BLOW AWAY
 *  ANY APPLICATION CURRENTLY IN CLIENT RAM SPACE.
 */
int
_tfsclean(TDEV *tdp, int notused, int verbose)
{
	ulong	appramstart;
	TFILE	*tfp, *lasttfp;
	uchar	*tbuf, *cp1, *cp2;
	int		dtot, nfadd, len, err, chkstat;

	if (TfsCleanEnable < 0)
		return(TFSERR_CLEANOFF);

	appramstart = getAppRamStart();

	/* Determine how many "dead" files exist. */
	dtot = 0;
	tfp = (TFILE *)tdp->start;
	while(validtfshdr(tfp)) {
		if (!TFS_FILEEXISTS(tfp))
			dtot++;
		tfp = nextfp(tfp,tdp);
	}

	if (dtot == 0)
		return(TFS_OKAY);

	printf("TFS device '%s' non-powersafe defragmentation\n",tdp->prefix);

	tbuf = (uchar *)appramstart;
	lasttfp = tfp = (TFILE *)(tdp->start);
	nfadd = tdp->start;
	while(validtfshdr(tfp)) {
		if (TFS_FILEEXISTS(tfp)) {
			len = TFS_SIZE(tfp) + sizeof(struct tfshdr);
			if (len % TFS_FSIZEMOD)
				len += TFS_FSIZEMOD - (len % TFS_FSIZEMOD);
			nfadd += len;
			if (s_memcpy((char *)tbuf,(char *)tfp,len,0,0) != 0)
				return(TFSERR_MEMFAIL);
			
			((struct tfshdr *)tbuf)->next = (struct tfshdr *)nfadd;
			tbuf += len;
		}
		lasttfp = tfp;
		tfp = nextfp(tfp,tdp);
	}

	/* We've now copied all of the active files from flash to ram.
	 * Now we want to see how much of the flash space needs to be
	 * erased.  We only need to erase the sectors that have changed...
	 */
	cp1 = (uchar *)tdp->start;
	cp2 = (uchar *)appramstart;
	while(cp2 < tbuf) {
		if (*cp1 != *cp2)
			break;
		cp1++; cp2++;
	}
#if INCLUDE_FLASH
	if ((cp2 != tbuf) || (!TFS_FILEEXISTS(lasttfp))) {
		int first, last;
		
		if (addrtosector(cp1,&first,0,0) == -1)
			return(TFSERR_FLASHFAILURE);
		
		if (addrtosector((uchar *)tdp->end,&last,0,0) == -1)
			return(TFSERR_FLASHFAILURE);
		printf("Erasing sectors %d-%d...\n",first,last);
		while(first<last) {
			if (flasherase(first++) == 0)
				return(TFSERR_FLASHFAILURE);
		}
	}
#endif

	/* Copy data placed in RAM back to flash: */
	printf("Restoring flash...\n");
	if (TFS_DEVTYPE_ISRAM(tdp)) {
		memcpy((char *)(tdp->start),(char *)appramstart,
			(tbuf-(uchar*)appramstart));
	}
	else {
#if INCLUDE_FLASH
		err = AppFlashWrite((uchar *)(tdp->start),(uchar *)appramstart,
			(tbuf-(uchar*)appramstart));
		if (err < 0)
#endif
			return(TFSERR_FLASHFAILURE);
	}

	/* All defragmentation is done, so verify sanity of files... */
	chkstat = tfscheck(tdp,verbose);

	return(chkstat);
}
Пример #3
0
void
BoardInfoInit(void)
{
    short   len;
    ushort  crc;
    struct  boardinfo *bip;
    int     maxpromptsize, erased;
    struct  boardinfoverify *bipv;
    uchar   buf[BOARDINFO_BUFMAX];
    char    c, snum[8], prfmt[16], *prefill;

    sprintf(snum,"%d",BOARDINFO_SECTOR);

    /* Step through each bip entry and see if the data area is either
     * empty or the crc16 passed.  If either is true, then allow
     * If every entry in the board-information area is either empty
     * or the crc test passes, we can just return...
     */
    erased = 0;
    maxpromptsize = 0;
    boardinfo_error = 0;
    bip = boardinfotbl;
    while((bip->array) && (!boardinfo_error)) {
        BINFOPRINT(("Boardinfo item: %s (%s)",bip->varname,bip->prompt));
        if(bip->array[0] != 0xff) {
            BINFOPRINT((" not"));
            bipv = (struct boardinfoverify *)&bip->array[bip->size-BIVSIZE];

            /* If len and crc are set, then use those fields to sanity
             * check the data...
             */
            if((bipv->len != 0xffff) && (bipv->crc16 != 0xffff)) {
                if((bipv->len > bip->size) ||
                        (xcrc16(bip->array,bipv->len) != bipv->crc16)) {
                    boardinfo_error = 1;
                }
            }
        } else {
            erased++;
        }
        BINFOPRINT((" erased\n"));

        /* Gather data to determine the largest prompt... */
        len = strlen(bip->prompt);
        if(len > maxpromptsize) {
            maxpromptsize = len;
        }
        bip++;
    }

    /* If there was no error, and the board info area is not erased,
     * we return here assuming the data is valid.
     */
    if((boardinfo_error == 0) && (erased == 0)) {
        sectorProtect(snum,1);
        return;
    }

    /* If there was some kind of error reading any of the fields in the
     * board-info area, then either return or clear the error and interact
     * with the user to re-load the data...
     */
    if(boardinfo_error != 0) {
#ifdef BOARDINFO_REENTER_ON_ERROR
        printf("\nError reading board-info data, re-enter data...");
        boardinfo_error = 0;
#else
        printf("\nError reading board-info data in sector %d.\n",
               BOARDINFO_SECTOR);
        return;
#endif
    }

    sprintf(prfmt,"%%%ds : ",maxpromptsize);

    printf("%s: board information field initialization...\n",PLATFORM_NAME);

    /* Un-protect the sector used for board information...
     */
    sectorProtect(snum,0);

    do {
        /* Erase the sector used for board information...
         */
        if(AppFlashErase(BOARDINFO_SECTOR) < 0) {
            boardinfo_error = 1;
            break;
        }

        /* Step through each entry in the boardinfo table and query
         * the user for input to be stored...
         */
        bip = boardinfotbl;
        while(bip->array) {
            bipv = (struct boardinfoverify *)&bip->array[bip->size-BIVSIZE];

            if(bip->def) {
                prefill = bip->def;
            } else {
                prefill = 0;
            }

            printf(prfmt,bip->prompt);
            len = 0;
            if(getline_p((char *)buf,bip->size-BIVSIZE,0,prefill) != 0) {
                len = strlen(buf)+1;
                if(AppFlashWrite(bip->array,buf,len) < 0) {
                    boardinfo_error = 1;
                    break;
                }
                crc = xcrc16(buf,len);
            }
            if(len) {
                if(AppFlashWrite((uchar *)(&bipv->len),
                                 (uchar *)&len,sizeof(len)) < 0) {
                    boardinfo_error = 1;
                    break;
                }
                if(AppFlashWrite((uchar *)(&bipv->crc16),
                                 (uchar *)&crc,sizeof(crc)) < 0) {
                    boardinfo_error = 1;
                    break;
                }
            }
            bip++;
        }
        if(boardinfo_error) {
            break;
        }

        bip = boardinfotbl;
        printf("\nNew system settings:\n\n");
        while(bip->array) {
#ifdef BOARDINFO_SHOW_RAW
            printMem(bip->array,bip->size,1);
#else
            printf("%24s: %s\n",bip->prompt,
                   bip->array[0] == 0xff ? "" : (char *)bip->array);
#endif
            bip++;
        }
        putstr("\nHit ENTER to accept, any other key to re-enter...");
        c = getchar();
        putchar('\n');

    } while((c != '\r') && (c != '\n'));

    sectorProtect(snum,1);
}