From 246ff98ae5b16ef0e19fe082a9c900e9169a1f7b Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 14 Jan 2010 13:33:53 +0800 Subject: [PATCH] Bugfixes and UDI Updates - Added UDI to the tree - Bugfixing FAT filesystem (Fixed EOC handling in FindDir) > Still a bug in ReadDir that causes garbage to be read --- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86/Makefile | 1 + Kernel/debug.c | 34 +++++++++++++++++++++ Kernel/modules.c | 2 +- Kernel/vfs/fs/fat.c | 64 +++++++++++++++++++--------------------- Makefile.cfg | 2 +- Modules/FDD/fdd.c | 1 + Modules/UDI/logging.c | 2 ++ 8 files changed, 72 insertions(+), 36 deletions(-) diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 1f36a5a3..cd91d84c 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1295 +BUILD_NUM = 1315 diff --git a/Kernel/arch/x86/Makefile b/Kernel/arch/x86/Makefile index 319c8f6f..87dd2b23 100644 --- a/Kernel/arch/x86/Makefile +++ b/Kernel/arch/x86/Makefile @@ -32,3 +32,4 @@ endif A_OBJ = start.ao main.o lib.o desctab.ao errors.o irq.o A_OBJ += mm_phys.o mm_virt.o A_OBJ += proc.o time.o +#A_OBJ += gdb_stub.o diff --git a/Kernel/debug.c b/Kernel/debug.c index ea303790..8404fc1d 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -8,6 +8,7 @@ #define DEBUG_TO_E9 1 #define DEBUG_TO_SERIAL 1 #define SERIAL_PORT 0x3F8 +#define GDB_SERIAL_PORT 0x2F8 // === IMPORTS === extern void Threads_Dump(); @@ -16,8 +17,41 @@ extern void Threads_Dump(); int gDebug_Level = 0; int giDebug_KTerm = -1; int gbDebug_SerialSetup = 0; + int gbGDB_SerialSetup = 0; // === CODE === +int putDebugChar(char ch) +{ + if(!gbGDB_SerialSetup) { + outb(GDB_SERIAL_PORT + 1, 0x00); // Disable all interrupts + outb(GDB_SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(GDB_SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(GDB_SERIAL_PORT + 1, 0x00); // (hi byte) + outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(GDB_SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it + outb(GDB_SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + gbDebug_SerialSetup = 1; + } + while( (inb(GDB_SERIAL_PORT + 5) & 0x20) == 0 ); + outb(GDB_SERIAL_PORT, ch); + return 0; +} +int getDebugChar() +{ + if(!gbGDB_SerialSetup) { + outb(GDB_SERIAL_PORT + 1, 0x00); // Disable all interrupts + outb(GDB_SERIAL_PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + outb(GDB_SERIAL_PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + outb(GDB_SERIAL_PORT + 1, 0x00); // (hi byte) + outb(GDB_SERIAL_PORT + 3, 0x03); // 8 bits, no parity, one stop bit + outb(GDB_SERIAL_PORT + 2, 0xC7); // Enable FIFO with 14-byte threshold and clear it + outb(GDB_SERIAL_PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + gbDebug_SerialSetup = 1; + } + while( (inb(GDB_SERIAL_PORT + 5) & 1) == 0) ; + return inb(GDB_SERIAL_PORT); +} + static void E9(char ch) { if(giDebug_KTerm != -1) diff --git a/Kernel/modules.c b/Kernel/modules.c index b2f45352..93de973d 100644 --- a/Kernel/modules.c +++ b/Kernel/modules.c @@ -6,7 +6,7 @@ #include #define USE_EDI 0 -#define USE_UDI 0 +#define USE_UDI 1 // === PROTOTYPES === int Modules_LoadBuiltins(); diff --git a/Kernel/vfs/fs/fat.c b/Kernel/vfs/fs/fat.c index a18f9511..984c9b4f 100644 --- a/Kernel/vfs/fs/fat.c +++ b/Kernel/vfs/fs/fat.c @@ -256,17 +256,23 @@ static Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster) #if !CACHE_FAT Uint32 ofs = Disk->bootsect.resvSectCount*512; #endif - ENTER("iHandle xCluster", handle, cluster); + ENTER("pDisk xCluster", Disk, cluster); #if CACHE_FAT val = Disk->FATCache[cluster]; + if(Disk->type == FAT12 && val == EOC_FAT12) val = -1; + if(Disk->type == FAT16 && val == EOC_FAT16) val = -1; + if(Disk->type == FAT32 && val == EOC_FAT32) val = -1; #else if(Disk->type == FAT12) { VFS_ReadAt(Disk->fileHandle, ofs+(cluster>>1)*3, 3, &val); val = (cluster&1 ? val&0xFFF : val>>12); + if(val == EOC_FAT12) val = -1; } else if(Disk->type == FAT16) { VFS_ReadAt(Disk->fileHandle, ofs+cluster*2, 2, &val); + if(val == EOC_FAT16) val = -1; } else { VFS_ReadAt(Disk->fileHandle, ofs+cluster*4, 4, &val); + if(val == EOC_FAT32) val = -1; } #endif /*CACHE_FAT*/ LEAVE('x', val); @@ -278,6 +284,7 @@ static Uint32 FAT_int_GetFatValue(tFAT_VolInfo *Disk, Uint32 cluster) static void FAT_int_ReadCluster(int Handle, Uint32 Cluster, int Length, void *Buffer) { ENTER("iHandle xCluster iLength pBuffer", Handle, Cluster, Length, Buffer); + //Log("Cluster = %i (0x%x)", Cluster, Cluster); VFS_ReadAt( gFAT_Disks[Handle].fileHandle, (gFAT_Disks[Handle].firstDataSect + (Cluster-2)*gFAT_Disks[Handle].bootsect.spc ) @@ -299,7 +306,6 @@ Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer) int i, cluster, pos; int bpc; void *tmpBuf; - Uint eocMarker; tFAT_VolInfo *disk = &gFAT_Disks[node->ImplInt]; ENTER("Xoffset Xlength pbuffer", offset, length, buffer); @@ -312,17 +318,6 @@ Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer) // Cluster is stored in Inode Field cluster = node->Inode; - // Get EOC Marker - if (disk->type == FAT12) eocMarker = EOC_FAT12; - else if(disk->type == FAT16) eocMarker = EOC_FAT16; - else if(disk->type == FAT32) eocMarker = EOC_FAT32; - else { - Log("ERROR: Unsupported FAT Variant.\n"); - free(tmpBuf); - LEAVE('i', 0); - return 0; - } - // Sanity Check offset if(offset > node->Size) { //LOG("Reading past EOF (%i > %i)", offset, node->Size); @@ -351,8 +346,10 @@ Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer) //Skip previous clusters for(i=preSkip;i--;) { cluster = FAT_int_GetFatValue(disk, cluster); - if(cluster == eocMarker) { + if(cluster == -1) { Warning("FAT_Read - Offset is past end of cluster chain mark"); + LEAVE('i', 0); + return 0; } } @@ -391,7 +388,7 @@ Uint64 FAT_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer) memcpy((void*)(buffer+pos), tmpBuf, bpc); pos += bpc; cluster = FAT_int_GetFatValue(disk, cluster); - if(cluster == eocMarker) { + if(cluster == -1) { Warning("FAT_Read - Read past End of Cluster Chain"); free(tmpBuf); LEAVE('i', 0); @@ -486,6 +483,7 @@ tVFS_Node *FAT_int_CreateNode(tVFS_Node *parent, fat_filetable *ft, char *LongFi // Set Other Data node.Inode = ft->cluster | (ft->clusterHi<<16); node.Size = ft->size; + LOG("ft->size = %i", ft->size); node.ImplInt = parent->ImplInt; node.UID = 0; node.GID = 0; node.NumACLs = 1; @@ -612,27 +610,23 @@ char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos) // Get Byte Offset and skip offset = dirpos * sizeof(fat_filetable); - preSkip = (offset >> 9) / disk->bootsect.spc; // >>9 == /512 + preSkip = offset / (512 * disk->bootsect.spc); + LOG("disk->bootsect.spc = %i", disk->bootsect.spc); + LOG("dirNode->size = %i", dirNode->Size); cluster = dirNode->Inode; // Cluster ID // Do Cluster Skip // - Pre FAT32 had a reserved area for the root. - if( !(disk->type != FAT32 && cluster == disk->rootOffset) ) + if( disk->type == FAT32 || cluster != disk->rootOffset ) { //Skip previous clusters for(a=preSkip;a--;) { cluster = FAT_int_GetFatValue(disk, cluster); + // Check for end of cluster chain + if(cluster == -1) { LEAVE('n'); return NULL;} } } - // Check for end of cluster chain - if((disk->type == FAT12 && cluster == EOC_FAT12) - || (disk->type == FAT16 && cluster == EOC_FAT16) - || (disk->type == FAT32 && cluster == EOC_FAT32)) { - LEAVE('n'); - return NULL; - } - // Bounds Checking (Used to spot heap overflows) if(cluster > disk->clusterCount + 2) { @@ -642,7 +636,7 @@ char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos) return NULL; } - LOG("cluster=0x%x, dirpos=%i\n", cluster, dirpos); + LOG("cluster=0x%x, dirpos=%i", cluster, dirpos); // Compute Offsets // - Pre FAT32 cluster base (in sectors) @@ -659,7 +653,7 @@ char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos) else offset += (dirpos / 16) % disk->bootsect.spc; // Offset in sector - a = dirpos & 0xF; + a = dirpos % 16; LOG("offset=%i, a=%i", (Uint)offset, a); @@ -668,7 +662,7 @@ char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos) LOG("name[0] = 0x%x", (Uint8)fileinfo[a].name[0]); //Check if this is the last entry - if(fileinfo[a].name[0] == '\0') { + if( fileinfo[a].name[0] == '\0' ) { dirNode->Size = dirpos; LOG("End of list"); LEAVE('n'); @@ -676,8 +670,8 @@ char *FAT_ReadDir(tVFS_Node *dirNode, int dirpos) } // Check for empty entry - if((Uint8)fileinfo[a].name[0] == 0xE5) { - LOG("Empty Entry\n"); + if( (Uint8)fileinfo[a].name[0] == 0xE5 ) { + LOG("Empty Entry"); LEAVE('p', VFS_SKIP); return VFS_SKIP; // Skip } @@ -765,8 +759,10 @@ tVFS_Node *FAT_FindDir(tVFS_Node *node, char *name) ENTER("pnode sname", node, name); // Fast Returns - if(!name) return NULL; - if(name[0] == '\0') return NULL; + if(!name || name[0] == '\0') { + LEAVE('n'); + return NULL; + } #if USE_LFN lfn = FAT_int_GetLFN(node); @@ -783,6 +779,7 @@ tVFS_Node *FAT_FindDir(tVFS_Node *node, char *name) { // Load sector if((i & 0xF) == 0) { + //Log("FAT_FindDir: diskOffset = 0x%x", diskOffset); VFS_ReadAt(disk->fileHandle, diskOffset, 512, fileinfo); diskOffset += 512; } @@ -822,7 +819,7 @@ tVFS_Node *FAT_FindDir(tVFS_Node *node, char *name) // Get Real Filename FAT_int_ProperFilename(tmpName, fileinfo[i&0xF].name); - LOG("tmpName = '%s'\n", tmpName); + LOG("tmpName = '%s'", tmpName); //Only Long name is case sensitive, 8.3 is not #if USE_LFN @@ -857,6 +854,7 @@ tVFS_Node *FAT_FindDir(tVFS_Node *node, char *name) if( dirCluster == disk->rootOffset && disk->type != FAT32 ) continue; dirCluster = FAT_int_GetFatValue(disk, dirCluster); + if(dirCluster == -1) break; diskOffset = (disk->firstDataSect+(dirCluster-2)*disk->bootsect.spc)*512; } } diff --git a/Makefile.cfg b/Makefile.cfg index da612a94..3157e962 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -25,7 +25,7 @@ endif FILESYSTEMS = fat DRIVERS = ata_x86 -MODULES = FS_Ext2 FDD NE2000 BochsGA IPStack +MODULES = FS_Ext2 FDD NE2000 BochsGA IPStack UDI DYNMODS = USB # UDI diff --git a/Modules/FDD/fdd.c b/Modules/FDD/fdd.c index 8227cb5a..69d3a559 100644 --- a/Modules/FDD/fdd.c +++ b/Modules/FDD/fdd.c @@ -635,6 +635,7 @@ int FDD_int_GetDims(int type, int lba, int *c, int *h, int *s, int *spt) *s = (lba % 18) + 1; *c = lba / 36; *h = (lba / 18) & 1; + //Log("1440k - lba=%i(0x%x), *s=%i,*c=%i,*h=%i", lba, lba, *s, *c, *h); break; // 2880Kb 3.5" diff --git a/Modules/UDI/logging.c b/Modules/UDI/logging.c index a083413e..2e58e373 100644 --- a/Modules/UDI/logging.c +++ b/Modules/UDI/logging.c @@ -14,3 +14,5 @@ void udi_log_write( udi_log_write_call_t *callback, udi_cb_t *gcb, { Log("UDI Log"); } + +EXPORT(udi_log_write); -- 2.20.1