# HG changeset patch # User Jonathan Pevarnek # Date 1302284518 14400 # Node ID eda059d7410024e786b0a8c37fdcca2d62b098e6 # Parent eda962110e0e92264fa8e9ab5437c35712a05b9b Started to librarize (is that a word) the filesystem diff -r eda962110e0e -r eda059d74100 Makefile --- a/Makefile Fri Apr 08 10:33:40 2011 -0400 +++ b/Makefile Fri Apr 08 13:41:58 2011 -0400 @@ -13,9 +13,9 @@ BINS=sarpn dynamic testFS -sarpn_OBJS=src/sarpn.o arch/arch.a src/std.o src/stack.o src/operations.o src/math.o -dynamic_OBJS=src/dynamic.o arch/arch.a src/std.o src/stack.o -testFS_OBJS=src/testFS.o arch/arch.a src/std.o +sarpn_OBJS=src/sarpn.o src/std.o src/stack.o src/operations.o src/math.o arch/arch.a +dynamic_OBJS=src/dynamic.o src/std.o src/stack.o arch/arch.a +testFS_OBJS=src/testFS.o src/std.o src/fs.o arch/arch.a ARCH_OBJS=arch/io.o arch/cons.o arch/ebcdic.o arch/fba.o arch/ioint.o @@ -28,7 +28,7 @@ clean: rm -f $(sarpn_OBJS) rm -f $(dynamic_OBJS) - rm -f $(fs_OBJS) + rm -f $(testFS_OBJS) rm -f $(ARCH_OBJS) rm -f $(BINS) rm -f loader.bin ipl/*.o ipl/*.rto ipl/ipl_ccws.S cscope.out @@ -94,9 +94,10 @@ # DO NOT DELETE src/dynamic.o: include/std.h include/operations.h include/stack.h +src/fs.o: include/fs.h src/operations.o: include/operations.h include/std.h include/stack.h src/operations.o: include/math.h src/sarpn.o: include/std.h include/operations.h include/stack.h src/stack.o: include/stack.h include/std.h src/std.o: include/std.h -src/testFS.o: include/std.h +src/testFS.o: include/std.h include/fs.h diff -r eda962110e0e -r eda059d74100 include/fs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/fs.h Fri Apr 08 13:41:58 2011 -0400 @@ -0,0 +1,39 @@ +#ifndef __FS_H +#define __FS_H + +struct SUPERBLOCK { + u32 magic; // == 0x42420374 + u32 root_inode; // the disk block containing the root inode + u32 nblocks; // number of block on the disk + u32 _pad[253]; // unused (should be '\0' filled) +}; +typedef struct SUPERBLOCK Superblock; + +struct INODE { + u32 size; // file length in bytes + u32 _pad0; // unused (should be 0) + u64 ctime; // creation time stamp + u64 mtime; // last modification time stamp + u16 nblocks; // number of data blocks in this file + u16 _pad1; // unused (should be 0) + u32 _pad2; // unused (should be 0) + u32 blocks[248]; // file block ptrs +}; +typedef struct INODE Inode; + +struct DIRENTRY { //32 bytes + char fname[28]; + u32 inode; +}; +typedef struct DIRENTRY Direntry; + +int fsInit(u32 devnum); +void listFiles(); +u32 lookupFile(char *fname); +u32 getFSize(u32 fid); +int getFData(u32 fid, void *ptr); +void printFname(char *name); +void getFname(char *fname); +int fnameCmp(const char *a, const char *b); + +#endif //__FSH_H diff -r eda962110e0e -r eda059d74100 src/fs.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/fs.c Fri Apr 08 13:41:58 2011 -0400 @@ -0,0 +1,125 @@ +#include +#include + +static int loadToCache(u32 fid); +static int readFSBlock(u32 dev, u32 blkno, void *fsBlock); + +static u32 DevID; +//static Superblock sb; //the superblock +static Direntry Direntries[32]; +static int NFiles; + +static u32 CacheID = 0; +static Inode Cached; + +int fsInit(u32 devnum) +{ + DevID = find_dev(0x100); + Superblock sb; //the superblock + if(readFSBlock(DevID, 1, &sb)) return -1; + Inode rootINode; + if(readFSBlock(DevID, sb.root_inode, &rootINode)) return -1; + NFiles = rootINode.size/sizeof(Direntry); + if(NFiles > 32) return -1; //for the moment, I do not feel like having support + //for this. TODO add support + int i; + for(i = 0; i*32 < NFiles; i++) { //this will only run once... It is useless + if(readFSBlock(DevID, rootINode.blocks[i], Direntries)) return -1; + } + return 0; +} + +void listFiles() +{ + Direntry *dp; + for(dp = Direntries; dp - Direntries < NFiles; dp++) + printFname(dp->fname), putline("\n", 1); +} + +u32 lookupFile(char *fname) +{ + Direntry *dp; + for(dp = Direntries; dp - Direntries < NFiles; dp++) { + if(!fnameCmp(fname, dp->fname)) { + if(loadToCache(dp->inode)) return 0; + return dp->inode; + } + } + return 0; +} + +//REQUIRES: Valid loadable fid +u32 getFSize(u32 fid) +{ + loadToCache(fid); + return Cached.size; +} + + +//REQUIRES: point is large enough to hold everything +int getFData(u32 fid, void *ptr) +{ + int i; + loadToCache(fid); + u32 size = Cached.size; + u16 nBlocks = Cached.nblocks; + for(i = 0; i < nBlocks; i++) { + if(size >= 1024) { + if(readFSBlock(DevID, Cached.blocks[i], ptr)) return -1; + ptr += 1024; + size -= 1024; + } else { + u8 *point = ptr; + u8 buffer[1024]; + if(readFSBlock(DevID, Cached.blocks[i], buffer)) return -1; + for(i = 0; i < size; i++, point++) { + *point = buffer[i]; + } + break; //it should do this anyways but... + } + } + return 0; +} + + +void printFname(char *name) +{ + putline(name, 28); +} + +//Sets name to contain a filename entered by the user +//REQUIRES: fname is 28 characters long +void getFname(char *fname) +{ + int chars = getline(fname, 28); + for(;chars < 28; chars++) { + fname[chars] = ' '; + } +} + +//Checks whether two file names are equal +int fnameCmp(const char *a, const char *b) +{ + int i; + for(i = 0; i < 28; i++, a++, b++) { + if(*a - *b) return *a - *b; + } + return 0; +} + +static int loadToCache(u32 fid) +{ + if(CacheID == fid) return 0; + if(readFSBlock(DevID, fid, &Cached)) return -1; + CacheID = fid; + return 0; +} + +//REQUIRES: fsBlock points to an object with size at least 1024 +//EFFECTS: Sets fsBlock to be equal +static int readFSBlock(u32 dev, u32 blkno, void *fsBlock) +{ + if(fba_read_blk(dev, blkno*2, fsBlock)) return 1; + if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1; + return 0; +} diff -r eda962110e0e -r eda059d74100 src/testFS.c --- a/src/testFS.c Fri Apr 08 10:33:40 2011 -0400 +++ b/src/testFS.c Fri Apr 08 13:41:58 2011 -0400 @@ -1,73 +1,5 @@ #include - -struct SUPERBLOCK { - u32 magic; // == 0x42420374 - u32 root_inode; // the disk block containing the root inode - u32 nblocks; // number of block on the disk - u32 _pad[253]; // unused (should be '\0' filled) -}; -typedef struct SUPERBLOCK Superblock; - -struct INODE { - u32 size; // file length in bytes - u32 _pad0; // unused (should be 0) - u64 ctime; // creation time stamp - u64 mtime; // last modification time stamp - u16 nblocks; // number of data blocks in this file - u16 _pad1; // unused (should be 0) - u32 _pad2; // unused (should be 0) - u32 blocks[248]; // file block ptrs -}; -typedef struct INODE Inode; - -struct DIRENTRY { //32 bytes - char fname[28]; - u32 inode; -}; -typedef struct DIRENTRY Direntry; - -//REQUIRES: fsBlock points to an object with size at least 1024 -//EFFECTS: Sets fsBlock to be equal -int readFSBlock(u32 dev, u32 blkno, void *fsBlock) -{ - if(fba_read_blk(dev, blkno*2, fsBlock)) return 1; - if(fba_read_blk(dev, blkno*2 + 1, fsBlock + 512)) return 1; - return 0; -} - -void printFname(char *name) -{ - putline(name, 28); -} - -//Sets name to contain a filename entered by the user -//REQUIRES: name is 28 characters long -void getFname(char *fname) -{ - int chars = getline(fname, 28); - for(;chars < 28; chars++) { - fname[chars] = ' '; - } -} - -//Checks whether two file names are equal -int fnameCmp(const char *a, const char *b) -{ - int i; - for(i = 0; i < 28; i++, a++, b++) { - if(*a - *b) return *a - *b; - } - return 0; -} - -//Finds the item within an array of filenames with the same name as fname -int fnameLookup(char *fname, const Direntry array[], int last) -{ - int i; - for(i = 0; i < last; i++) - if(!fnameCmp(fname, array[i].fname)) return i; - return last; -} +#include void dumpText(char *text, int size) { @@ -82,68 +14,31 @@ { init_io_int(); init_console(); + malloc_init(__memsize - HEAP_START); char buffer[256]; - int i; - - u32 dev = find_dev(0x100); - Superblock sb; - if(readFSBlock(dev, 1, &sb)) { //get the super block - sPrint("ERROR\n"); - goto END; - } - Inode root; - if(readFSBlock(dev, sb.root_inode, &root)) { //get the root inode - sPrint("ERROR\n"); - goto END; - } - int nFiles = root.size/sizeof(Direntry); - //calculate how many files (assume less than 32 for the moment) - //TODO get rid of assumption - Direntry direntries[32]; - if(readFSBlock(dev, root.blocks[0], direntries)) { //get the "first 32" files - sPrint("ERROR\n"); - goto END; - } + if(fsInit(0x100)) goto END; while(1) { //Prints off the name of each file - Direntry *dp; - for(dp = direntries; dp - direntries < nFiles; dp++) { - printFname(dp->fname), sPrint("\n"); - } + listFiles(); char fname[28]; sPrint("Please enter the file to read: "); getFname(fname); - int file = fnameLookup(fname, direntries, nFiles); - - u32 fileLoc = direntries[file].inode; - if(fileLoc == nFiles) continue; - - Inode fileToRead; - if(readFSBlock(dev, fileLoc, &fileToRead)) { - sPrint("ERROR\n"); - goto END; - } + u32 fid = lookupFile(fname); + if(!fid) continue; //if fid is 0, the file was not found - u32 fileSize = fileToRead.size; - - for(i = 0; i < fileToRead.nblocks; i++) { - char text[1024]; - if(readFSBlock(dev, fileToRead.blocks[i], text)) { - sPrint("ERROR\n"); - goto END; - } - dumpText(text, (fileSize > 1024)?1024:fileSize); - fileSize -= 1024; - } + u32 fileSize = getFSize(fid); + char *text = malloc(fileSize); + text = text; + getFData(fid, text); + dumpText(text, fileSize); + free(text); } - END: sPrint("DONE\n"); for(;;) { sGet(buffer, 0); } } -