From 72212c137c574b564723327af751c4054c7cfca6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 11 Apr 2006 19:09:16 -0400 Subject: Initial commit --- mkfs.ffs2.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 mkfs.ffs2.c (limited to 'mkfs.ffs2.c') diff --git a/mkfs.ffs2.c b/mkfs.ffs2.c new file mode 100644 index 0000000..36204dd --- /dev/null +++ b/mkfs.ffs2.c @@ -0,0 +1,239 @@ +// Description +// $Id: mkfs.ffs2.c,v 1.5 2005/11/07 11:15:12 gleixner Exp $ +/* ###################################################################### + + Microsoft Flash File System 2 + + Information for the FFS2.0 was found in Microsoft's knowledge base, + http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/specs/S346A.HTM + Try searching for "Flash File System" if it has been moved + + This program creates an empty file system. + + ##################################################################### */ + +#include +#include +#include +#include +#include +#include +#include + +#include = argc) + { + fprintf(stderr,"You must specify a device\n"); + return 16; + } + + // Open and size the device + if ((Fd = open(argv[Device],O_RDWR)) < 0) + { + fprintf(stderr,"File open error\n"); + return 8; + } + if (ioctl(Fd,BLKGETSIZE,&Length) < 0) + { + Length = lseek(Fd,0,SEEK_END); + lseek(Fd,0,SEEK_SET); + } + else + Length *= 512; + + if ((Start + 1)*BlockSize > Length) + { + fprintf(stderr,"The flash is not large enough\n"); + } + + printf("Total size is %lu, %lu byte erase " + "blocks for %lu blocks with %lu spares.\n",Length,BlockSize, + Length/BlockSize,Spares); + if (Start != 0) + printf("Skiping the first %lu bytes\n",Start*BlockSize); + + if (ioctl(Fd,MEMGETINFO,&meminfo) == 0) + { + struct erase_info erase; + printf("Performing Flash Erase"); + fflush(stdout); + + erase.length = Length - Start*BlockSize; + erase.start = Start*BlockSize; + if (ioctl(Fd,MEMERASE,&erase) != 0) + { + perror("\nMTD Erase failure"); + close(Fd); + return 8; + } + printf(" done\n"); + } + else + { + for (I = Start; I <= Length/BlockSize; I++) + { + printf("Erase %u\r",I); + fflush(stdout); + if (EraseBlock(I) != 0) + { + perror(argv[Device]); + close(Fd); + return 8; + } + } + } + + for (I = 0; I != Length/BlockSize; I++) + { + struct ffs2_block block; + + // Write the block structure + memset(&block,0xFF,sizeof(block)); + block.EraseCount = 1; + block.BlockSeq = I; + block.BlockSeqChecksum = 0xFFFF ^ block.BlockSeq; + block.Status = (block.Status & (~FFS_STATE_MASK)) | FFS_STATE_READY; + + // Is Spare + if (I >= Length/BlockSize - Spares) + { + block.BlockSeq = 0xFFFF; + block.BlockSeqChecksum = 0xFFFF; + block.Status = (block.Status & (~FFS_STATE_MASK)) | FFS_STATE_SPARE; + } + + // Setup the boot record and the root record + if (I == 0) + { + struct ffs2_bootrecord boot; + struct ffs2_blockalloc alloc[2]; + unsigned char Tmp[300]; + struct ffs2_entry *root = (struct ffs2_entry *)Tmp; + + block.BootRecordPtr = 0; + block.Status = (block.Status & (~FFS_BOOTP_MASK)) | FFS_BOOTP_CURRENT; + + boot.Signature = 0xF1A5; + boot.SerialNumber = time(0); + boot.FFSWriteVersion = 0x200; + boot.FFSReadVersion = 0x200; + boot.TotalBlockCount = Length/BlockSize; + boot.SpareBlockCount = Spares; + boot.BlockLen = BlockSize; + boot.RootDirectoryPtr = 0x1; + boot.BootCodeLen = 0; + + memset(root,0xFF,sizeof(*root)); + root->Status = (root->Status & (~FFS_ENTRY_TYPEMASK)) | FFS_ENTRY_TYPEDIR; + root->NameLen = strlen("root"); + root->Time = (__u16)boot.SerialNumber; + root->Date = (__u16)(boot.SerialNumber >> 16); + root->VarStructLen = 0; + strcpy(root->Name,"root"); + + // Boot Block allocation structure + alloc[1].Status = (0xFF & (~FFS_ALLOC_SMASK)) | FFS_ALLOC_ALLOCATED; + alloc[1].Status &= 0xFF & (~FFS_ALLOC_EMASK); + alloc[1].Offset[0] = 0; + alloc[1].Offset[1] = 0; + alloc[1].Offset[2] = 0; + alloc[1].Len = FFS_SIZEOF_BOOT; + + // Root Dir allocation structure + alloc[0].Status = (0xFF & (~FFS_ALLOC_SMASK)) | FFS_ALLOC_ALLOCATED; + alloc[0].Offset[0] = FFS_SIZEOF_BOOT; + alloc[0].Offset[1] = 0; + alloc[0].Offset[2] = 0; + alloc[0].Len = FFS_SIZEOF_ENTRY + root->NameLen; + + // Write the two headers + if (lseek(Fd,BlockSize*(I+Start),SEEK_SET) < 0 || + write(Fd,&boot,FFS_SIZEOF_BOOT) != FFS_SIZEOF_BOOT || + write(Fd,root,FFS_SIZEOF_ENTRY + root->NameLen) != FFS_SIZEOF_ENTRY + root->NameLen) + { + perror("Failed writing headers"); + close(Fd); + return 8; + } + + // And the two allocation structures + if (lseek(Fd,BlockSize*(I+Start+1) - FFS_SIZEOF_BLOCK - sizeof(alloc), + SEEK_SET) <= 0 || + write(Fd,alloc,sizeof(alloc)) != sizeof(alloc)) + { + perror("Failed writing allocations"); + close(Fd); + return 8; + } + } + + if (lseek(Fd,BlockSize*(I+Start+1) - FFS_SIZEOF_BLOCK, + SEEK_SET) <= 0 || + write(Fd,&block,FFS_SIZEOF_BLOCK) != FFS_SIZEOF_BLOCK) + { + perror("Failed writing block"); + close(Fd); + return 8; + } + } + printf("\n"); + + return 0; +} -- cgit v1.2.3