Fixes and Cleanup
authorJohn Hodge <[email protected]>
Fri, 13 Nov 2009 07:09:46 +0000 (15:09 +0800)
committerJohn Hodge <[email protected]>
Fri, 13 Nov 2009 07:09:46 +0000 (15:09 +0800)
- Fixed text mode in BochsGA driver and hence set it to the VTerm default
- Moved Ext2 Filesystem driver to Modules tree (As FS_Ext2)
- Included root Makefile in git tree
- Slight changes to the in-process USB code
- Updated the README
- Inconcequential changes to other files

24 files changed:
Kernel/arch/x86/errors.c
Kernel/arch/x86/proc.c
Kernel/drv/vterm.c
Kernel/modules.c
Kernel/vfs/fs/ext2.c [deleted file]
Kernel/vfs/fs/fs_ext2.h [deleted file]
Makefile [new file with mode: 0644]
Makefile.cfg
Modules/BochsVBE/Makefile [deleted file]
Modules/BochsVBE/bochsvbe.c [deleted file]
Modules/FS_Ext2/Makefile [new file with mode: 0644]
Modules/FS_Ext2/dir.c [new file with mode: 0644]
Modules/FS_Ext2/ext2.c [new file with mode: 0644]
Modules/FS_Ext2/ext2_common.h [new file with mode: 0644]
Modules/FS_Ext2/ext2fs.h [new file with mode: 0644]
Modules/FS_Ext2/read.c [new file with mode: 0644]
Modules/FS_Ext2/write.c [new file with mode: 0644]
Modules/USB/uhci.c
Modules/USB/usb.h
README
Usermode/Libraries/libc.so_src/lib.h
Usermode/Libraries/libc.so_src/stub.c
Usermode/include/acess/devices.h
Usermode/include/acess/devices/terminal.h [new file with mode: 0644]

index d87b1c6..2f94972 100644 (file)
@@ -17,6 +17,12 @@ extern void Threads_Dump();
 void   Error_Backtrace(Uint eip, Uint ebp);
 
 // === CODE ===
+void __stack_chk_fail()
+{
+       Panic("FATAL ERROR: Stack Check Failed\n");
+       for(;;);
+}
+
 /**
  * \fn void ErrorHandler(tRegs *Regs)
  * \brief General Error Handler
index 5301401..d7f460f 100644 (file)
@@ -560,10 +560,11 @@ void Proc_Scheduler(int CPU)
        __asm__ __volatile__ ("mov %0, %%cr3"::"a"(gCurrentThread->MemState.CR3));
        // Switch threads
        __asm__ __volatile__ (
-               "mov %1, %%esp\n\t"
-               "mov %2, %%ebp\n\t"
-               "jmp *%3" : :
+               "mov %1, %%esp\n\t"     // Restore ESP
+               "mov %2, %%ebp\n\t"     // and EBP
+               "jmp *%3" : :   // And return to where we saved state (Proc_Clone or Proc_Scheduler)
                "a"(SWITCH_MAGIC), "b"(gCurrentThread->SavedState.ESP),
-               "d"(gCurrentThread->SavedState.EBP), "c"(gCurrentThread->SavedState.EIP));
+               "d"(gCurrentThread->SavedState.EBP), "c"(gCurrentThread->SavedState.EIP)
+               );
        for(;;);        // Shouldn't reach here
 }
index 09f85ff..87f71ed 100644 (file)
@@ -16,8 +16,8 @@
 #define MAX_INPUT_CHARS32      64
 #define MAX_INPUT_CHARS8       (MAX_INPUT_CHARS32*4)
 #define VT_SCROLLBACK  1       // 2 Screens of text
-#define DEFAULT_OUTPUT "VGA"
-//#define DEFAULT_OUTPUT       "BochsGA"
+//#define DEFAULT_OUTPUT       "VGA"
+#define DEFAULT_OUTPUT "BochsGA"
 #define DEFAULT_INPUT  "PS2Keyboard"
 #define        DEFAULT_WIDTH   80
 #define        DEFAULT_HEIGHT  25
@@ -197,7 +197,7 @@ int VT_Install(char **Arguments)
 void VT_InitOutput()
 {
        giVT_OutputDevHandle = VFS_Open(gsVT_OutputDevice, VFS_OPENFLAG_WRITE);
-       LOG("giVT_OutputDevHandle = %x\n", giVT_OutputDevHandle);
+       Log("giVT_OutputDevHandle = %x\n", giVT_OutputDevHandle);
        VT_SetTerminal( 0 );
 }
 
@@ -896,7 +896,7 @@ void VT_int_ChangeMode(tVTerm *Term, int NewMode)
 Uint8  *VT_Font_GetChar(Uint32 Codepoint);
 
 // === GLOBALS ===
-int    giVT_CharWidth = FONT_WIDTH;
+int    giVT_CharWidth = FONT_WIDTH+1;
 int    giVT_CharHeight = FONT_HEIGHT;
 
 // === CODE ===
@@ -909,13 +909,14 @@ void VT_Font_Render(Uint32 Codepoint, void *Buffer, int Pitch, Uint32 BGC, Uint3
        Uint8   *font;
        Uint32  *buf = Buffer;
         int    x, y;
+       
        font = VT_Font_GetChar(Codepoint);
        
        for(y = 0; y < FONT_HEIGHT; y ++)
        {
                for(x = 0; x < FONT_WIDTH; x ++)
                {
-                       if(*font & (1 << (FONT_WIDTH-x)))
+                       if(*font & (1 << (FONT_WIDTH-x-1)))
                                buf[x] = FGC;
                        else
                                buf[x] = BGC;
index b1d858c..a4e639b 100644 (file)
@@ -46,6 +46,7 @@ int Modules_LoadBuiltins()
                                        if(strcmp(deps[j], gKernelModules[k].Name) == 0)
                                                break;
                                }
+                               Log("%s requires %s\n", gKernelModules[i].Name, deps[j]);
                                if(k == giNumBuiltinModules) {
                                        Warning("Unable to find dependency '%s' for '%s' in kernel",
                                                deps[j], gKernelModules[i].Name);
@@ -64,6 +65,8 @@ int Modules_LoadBuiltins()
                for( i = 0; i < giNumBuiltinModules; i++ )
                {
                        if( baIsLoaded[i] )     continue;       // Ignore already loaded modules
+               
+                       deps = gKernelModules[i].Dependencies;
                        
                        if( deps )
                        {
@@ -75,6 +78,7 @@ int Modules_LoadBuiltins()
                                        }
                                        // `k` is assumed to be less than `giNumBuiltinModules`
                                        
+                                       Log("baIsLoaded[%i(%s)] = %i\n", k, deps[j], baIsLoaded[k]);
                                        // If a dependency failed, skip and mark as failed
                                        if( baIsLoaded[k] == -1 ) {
                                                baIsLoaded[i] = -1;
diff --git a/Kernel/vfs/fs/ext2.c b/Kernel/vfs/fs/ext2.c
deleted file mode 100644 (file)
index 0b60e54..0000000
+++ /dev/null
@@ -1,744 +0,0 @@
-/*\r
- * Acess OS\r
- * Ext2 Driver Version 1\r
- */\r
-/**\r
- * \file fs/ext2.c\r
- * \brief Second Extended Filesystem Driver\r
- * \todo Implement file full write support\r
- */\r
-#define DEBUG  1\r
-#define VERBOSE        0\r
-#include <common.h>\r
-#include <vfs.h>\r
-#include <modules.h>\r
-#include "fs_ext2.h"\r
-\r
-#define EXT2_UPDATE_WRITEBACK  1\r
-\r
-// === STRUCTURES ===\r
-typedef struct {\r
-        int    FD;\r
-        int    CacheID;\r
-       tVFS_Node       RootNode;\r
-       \r
-       tExt2_SuperBlock        SuperBlock;\r
-        int    BlockSize;\r
-        \r
-        int    GroupCount;\r
-       tExt2_Group             Groups[];\r
-} tExt2_Disk;\r
-\r
-// === PROTOTYPES ===\r
- int   Ext2_Install(char **Arguments);\r
-// Interface Functions\r
-tVFS_Node      *Ext2_InitDevice(char *Device, char **Options);\r
-void           Ext2_Unmount(tVFS_Node *Node);\r
-Uint64         Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);\r
-Uint64         Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);\r
-void           Ext2_CloseFile(tVFS_Node *Node);\r
-char           *Ext2_ReadDir(tVFS_Node *Node, int Pos);\r
-tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, char *FileName);\r
- int           Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);\r
-// Internal Helpers\r
- int           Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
-tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name);\r
- int           Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);\r
-Uint64         Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
-Uint32         Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
-Uint32         Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock);\r
-void           Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
-\r
-// === SEMI-GLOBALS ===\r
-MODULE_DEFINE(0, 0x5B /*v0.90*/, EXT2, Ext2_Install, NULL);\r
-tExt2_Disk     gExt2_disks[6];\r
- int   giExt2_count = 0;\r
-tVFS_Driver    gExt2_FSInfo = {\r
-       "ext2", 0, Ext2_InitDevice, Ext2_Unmount, NULL\r
-       };\r
-\r
-// === CODE ===\r
-\r
-/**\r
- * \fn int Ext2_Install(char **Arguments)\r
- * \brief Install the Ext2 Filesystem Driver\r
- */\r
-int Ext2_Install(char **Arguments)\r
-{\r
-       VFS_AddDriver( &gExt2_FSInfo );\r
-       return 1;\r
-}\r
-\r
-/**\r
- \fn tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
- \brief Initializes a device to be read by by the driver\r
- \param Device String - Device to read from\r
- \param Options        NULL Terminated array of option strings\r
- \return Root Node\r
-*/\r
-tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
-{\r
-       tExt2_Disk      *disk;\r
-        int    fd;\r
-        int    groupCount;\r
-       tExt2_SuperBlock        sb;\r
-       tExt2_Inode     inode;\r
-       \r
-       ENTER("sDevice pOptions", Device, Options);\r
-       \r
-       // Open Disk\r
-       fd = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);            //Open Device\r
-       if(fd == -1) {\r
-               Warning("[EXT2 ] Unable to open '%s'", Device);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Read Superblock at offset 1024\r
-       VFS_ReadAt(fd, 1024, 1024, &sb);        // Read Superblock\r
-       \r
-       // Sanity Check Magic value\r
-       if(sb.s_magic != 0xEF53) {\r
-               Warning("[EXT2 ] Volume '%s' is not an EXT2 volume", Device);\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Get Group count\r
-       groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
-       LOG("groupCount = %i", groupCount);\r
-       \r
-       // Allocate Disk Information\r
-       disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\r
-       if(!disk) {\r
-               Warning("[EXT2 ] Unable to allocate disk structure");\r
-               VFS_Close(fd);\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       disk->FD = fd;\r
-       memcpy(&disk->SuperBlock, &sb, 1024);\r
-       disk->GroupCount = groupCount;\r
-       \r
-       // Get an inode cache handle\r
-       disk->CacheID = Inode_GetHandle();\r
-       \r
-       // Get Block Size\r
-       LOG("s_log_block_size = 0x%x", sb.s_log_block_size);\r
-       disk->BlockSize = 1024 << sb.s_log_block_size;\r
-       \r
-       // Read Group Information\r
-       VFS_ReadAt(\r
-               disk->FD,\r
-               sb.s_first_data_block * disk->BlockSize + 1024,\r
-               sizeof(tExt2_Group)*groupCount,\r
-               disk->Groups\r
-               );\r
-       \r
-       #if VERBOSE\r
-       LOG("Block Group 0");\r
-       LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
-       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
-       LOG(".bg_inode_table = 0x%x", disk->Groups[0].bg_inode_table);\r
-       LOG("Block Group 1");\r
-       LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);\r
-       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);\r
-       LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
-       #endif\r
-       \r
-       // Get root Inode\r
-       Ext2_int_ReadInode(disk, 2, &inode);\r
-       \r
-       // Create Root Node\r
-       memset(&disk->RootNode, 0, sizeof(tVFS_Node));\r
-       disk->RootNode.Inode = 2;       // Root inode ID\r
-       disk->RootNode.ImplPtr = disk;  // Save disk pointer\r
-       disk->RootNode.Size = -1;       // Fill in later (on readdir)\r
-       disk->RootNode.Flags = VFS_FFLAG_DIRECTORY;\r
-       \r
-       disk->RootNode.ReadDir = Ext2_ReadDir;\r
-       disk->RootNode.FindDir = Ext2_FindDir;\r
-       //disk->RootNode.Relink = Ext2_Relink;\r
-       \r
-       // Complete root node\r
-       disk->RootNode.UID = inode.i_uid;\r
-       disk->RootNode.GID = inode.i_gid;\r
-       disk->RootNode.NumACLs = 1;\r
-       disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;\r
-       \r
-       #if DEBUG\r
-       LOG("inode.i_size = 0x%x", inode.i_size);\r
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
-       #endif\r
-       \r
-       LEAVE('p', &disk->RootNode);\r
-       return &disk->RootNode;\r
-}\r
-\r
-/**\r
- * \fn void Ext2_Unmount(tVFS_Node *Node)\r
- * \brief Close a mounted device\r
- */\r
-void Ext2_Unmount(tVFS_Node *Node)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       \r
-       VFS_Close( disk->FD );\r
-       Inode_ClearCache( disk->CacheID );\r
-       memset(disk, 0, sizeof(tExt2_Disk)+disk->GroupCount*sizeof(tExt2_Group));\r
-       free(disk);\r
-}\r
-\r
-/**\r
- * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
- * \brief Read from a file\r
- */\r
-Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       tExt2_Inode     inode;\r
-       Uint64  base;\r
-       Uint    block;\r
-       Uint64  remLen;\r
-       \r
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);\r
-       \r
-       // Get Inode\r
-       Ext2_int_GetInode(Node, &inode);\r
-       \r
-       // Sanity Checks\r
-       if(Offset >= inode.i_size) {\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       if(Offset + Length > inode.i_size)\r
-               Length = inode.i_size - Offset;\r
-       \r
-       block = Offset / disk->BlockSize;\r
-       Offset = Offset / disk->BlockSize;\r
-       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-       if(base == 0) {\r
-               Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       \r
-       // Read only block\r
-       if(Length <= disk->BlockSize - Offset)\r
-       {\r
-               VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);\r
-               LEAVE('X', Length);\r
-               return Length;\r
-       }\r
-       \r
-       // Read first block\r
-       remLen = Length;\r
-       VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);\r
-       remLen -= disk->BlockSize - Offset;\r
-       Buffer += disk->BlockSize - Offset;\r
-       block ++;\r
-       \r
-       // Read middle blocks\r
-       while(remLen > disk->BlockSize)\r
-       {\r
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-               if(base == 0) {\r
-                       Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);\r
-                       LEAVE('i', 0);\r
-                       return 0;\r
-               }\r
-               VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);\r
-               Buffer += disk->BlockSize;\r
-               remLen -= disk->BlockSize;\r
-               block ++;\r
-       }\r
-       \r
-       // Read last block\r
-       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-       VFS_ReadAt( disk->FD, base, remLen, Buffer);\r
-       \r
-       LEAVE('X', Length);\r
-       return Length;\r
-}\r
-\r
-/**\r
- * \fn Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
- * \brief Write to a file\r
- */\r
-Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       tExt2_Inode     inode;\r
-       Uint64  base;\r
-       Uint64  retLen;\r
-       Uint    block;\r
-       Uint64  allocSize;\r
-        int    bNewBlocks = 0;\r
-       \r
-       Debug_HexDump("Ext2_Write", Buffer, Length);\r
-       \r
-       Ext2_int_GetInode(Node, &inode);\r
-       \r
-       // Get the ammount of space already allocated\r
-       // - Round size up to block size\r
-       // - block size is a power of two, so this will work\r
-       allocSize = (inode.i_size + disk->BlockSize) & ~(disk->BlockSize-1);\r
-       \r
-       // Are we writing to inside the allocated space?\r
-       if( Offset < allocSize )\r
-       {\r
-               // Will we go out of it?\r
-               if(Offset + Length > allocSize) {\r
-                       bNewBlocks = 1;\r
-                       retLen = allocSize - Offset;\r
-               } else\r
-                       retLen = Length;\r
-               \r
-               // Within the allocated space\r
-               block = Offset / disk->BlockSize;\r
-               Offset %= disk->BlockSize;\r
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-               \r
-               // Write only block (if only one)\r
-               if(Offset + retLen <= disk->BlockSize) {\r
-                       VFS_WriteAt(disk->FD, base+Offset, retLen, Buffer);\r
-                       if(!bNewBlocks) return Length;\r
-                       goto addBlocks; // Ugh! A goto, but it seems unavoidable\r
-               }\r
-               \r
-               // Write First Block\r
-               VFS_WriteAt(disk->FD, base+Offset, disk->BlockSize-Offset, Buffer);\r
-               Buffer += disk->BlockSize-Offset;\r
-               retLen -= disk->BlockSize-Offset;\r
-               block ++;\r
-               \r
-               // Write middle blocks\r
-               while(retLen > disk->BlockSize)\r
-               {\r
-                       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-                       VFS_WriteAt(disk->FD, base, disk->BlockSize, Buffer);\r
-                       Buffer += disk->BlockSize;\r
-                       retLen -= disk->BlockSize;\r
-                       block ++;\r
-               }\r
-               \r
-               // Write last block\r
-               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
-               VFS_WriteAt(disk->FD, base, retLen, Buffer);\r
-               if(!bNewBlocks) return Length;  // Writing in only allocated space\r
-       }\r
-       \r
-addBlocks:\r
-       ///\todo Implement block allocation\r
-       Warning("[EXT2] File extending is not yet supported");\r
-       \r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn void Ext2_CloseFile(tVFS_Node *Node)\r
- * \brief Close a file (Remove it from the cache)\r
- */\r
-void Ext2_CloseFile(tVFS_Node *Node)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       Inode_UncacheNode(disk->CacheID, Node->Inode);\r
-       return ;\r
-}\r
-\r
-/**\r
- \fn char *Ext2_ReadDir(tVFS_Node *Node, int Pos)\r
- \brief Reads a directory entry\r
-*/\r
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)\r
-{\r
-       tExt2_Inode     inode;\r
-       char    namebuf[EXT2_NAME_LEN+1];\r
-       tExt2_DirEnt    dirent;\r
-       Uint64  Base;   // Block's Base Address\r
-        int    block = 0, ofs = 0;\r
-        int    entNum = 0;\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       Uint    size;\r
-       \r
-       ENTER("pNode iPos", Node, Pos);\r
-       \r
-       // Read directory's inode\r
-       Ext2_int_GetInode(Node, &inode);\r
-       size = inode.i_size;\r
-       \r
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
-       \r
-       // Find Entry\r
-       // Get First Block\r
-       // - Do this ourselves as it is a simple operation\r
-       Base = inode.i_block[0] * disk->BlockSize;\r
-       while(Pos -- && size > 0)\r
-       {\r
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);\r
-               ofs += dirent.rec_len;\r
-               size -= dirent.rec_len;\r
-               entNum ++;\r
-               \r
-               if(ofs >= disk->BlockSize) {\r
-                       block ++;\r
-                       if( ofs > disk->BlockSize ) {\r
-                               Warning("[EXT2] Directory Entry %i of inode %i extends over a block boundary, ignoring",\r
-                                       entNum-1, Node->Inode);\r
-                       }\r
-                       ofs = 0;\r
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );\r
-               }\r
-       }\r
-       \r
-       // Check for the end of the list\r
-       if(size <= 0) {\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Read Entry\r
-       VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );\r
-       //LOG("dirent.inode = %i", dirent.inode);\r
-       //LOG("dirent.rec_len = %i", dirent.rec_len);\r
-       //LOG("dirent.name_len = %i", dirent.name_len);\r
-       VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );\r
-       namebuf[ dirent.name_len ] = '\0';      // Cap off string\r
-       \r
-       \r
-       // Ignore . and .. (these are done in the VFS)\r
-       if( (namebuf[0] == '.' && namebuf[1] == '\0')\r
-       ||  (namebuf[0] == '.' && namebuf[1] == '.' && namebuf[2]=='\0')) {\r
-               LEAVE('p', VFS_SKIP);\r
-               return VFS_SKIP;        // Skip\r
-       }\r
-       \r
-       LEAVE('s', namebuf);\r
-       // Create new node\r
-       return strdup(namebuf);\r
-}\r
-\r
-/**\r
- \fn tVFS_Node *Ext2_FindDir(tVFS_Node *node, char *filename)\r
- \brief Gets information about a file\r
- \param node   vfs node - Parent Node\r
- \param filename       String - Name of file\r
- \return VFS Node of file\r
-*/\r
-tVFS_Node *Ext2_FindDir(tVFS_Node *Node, char *Filename)\r
-{\r
-       tExt2_Disk      *disk = Node->ImplPtr;\r
-       tExt2_Inode     inode;\r
-       char    namebuf[EXT2_NAME_LEN+1];\r
-       tExt2_DirEnt    dirent;\r
-       Uint64  Base;   // Block's Base Address\r
-        int    block = 0, ofs = 0;\r
-        int    entNum = 0;\r
-       Uint    size;\r
-       \r
-       // Read directory's inode\r
-       Ext2_int_GetInode(Node, &inode);\r
-       size = inode.i_size;\r
-       \r
-       // Get First Block\r
-       // - Do this ourselves as it is a simple operation\r
-       Base = inode.i_block[0] * disk->BlockSize;\r
-       // Find File\r
-       while(size > 0)\r
-       {\r
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);\r
-               VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );\r
-               namebuf[ dirent.name_len ] = '\0';      // Cap off string\r
-               // If it matches, create a node and return it\r
-               if(strcmp(namebuf, Filename) == 0)\r
-                       return Ext2_int_CreateNode( disk, dirent.inode, namebuf );\r
-               // Increment pointers\r
-               ofs += dirent.rec_len;\r
-               size -= dirent.rec_len;\r
-               entNum ++;\r
-               \r
-               // Check for end of block\r
-               if(ofs >= disk->BlockSize) {\r
-                       block ++;\r
-                       if( ofs > disk->BlockSize ) {\r
-                               Warning("[EXT2 ] Directory Entry %i of inode %i extends over a block boundary, ignoring",\r
-                                       entNum-1, Node->Inode);\r
-                       }\r
-                       ofs = 0;\r
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );\r
-               }\r
-       }\r
-       \r
-       return NULL;\r
-}\r
-\r
-/**\r
- * \fn int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)\r
- * \brief Create a new node\r
- */\r
-int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)\r
-{\r
-       return 0;\r
-}\r
-\r
-//==================================\r
-//=       INTERNAL FUNCTIONS       =\r
-//==================================\r
-\r
-\r
-/**\r
- * \fn int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
- * \brief Gets the inode descriptor for a node\r
- * \param Node node to get the Inode of\r
- * \param Inode        Destination\r
- */\r
-int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
-{\r
-       return Ext2_int_ReadInode(Node->ImplPtr, Node->Inode, Inode);\r
-}\r
-\r
-/**\r
- * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)\r
- * \brief Create a new VFS Node\r
- */\r
-tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)\r
-{\r
-       tExt2_Inode     inode;\r
-       tVFS_Node       retNode;\r
-       tVFS_Node       *tmpNode;\r
-       \r
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )\r
-               return NULL;\r
-       \r
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )\r
-               return tmpNode;\r
-       \r
-       \r
-       // Set identifiers\r
-       retNode.Inode = InodeID;\r
-       retNode.ImplPtr = Disk;\r
-       \r
-       // Set file length\r
-       retNode.Size = inode.i_size;\r
-       \r
-       // Set Access Permissions\r
-       retNode.UID = inode.i_uid;\r
-       retNode.GID = inode.i_gid;\r
-       retNode.NumACLs = 3;\r
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);\r
-       \r
-       //  Set Function Pointers\r
-       retNode.Read = Ext2_Read;\r
-       retNode.Write = Ext2_Write;\r
-       retNode.Close = Ext2_CloseFile;\r
-       \r
-       switch(inode.i_mode & EXT2_S_IFMT)\r
-       {\r
-       // Symbolic Link\r
-       case EXT2_S_IFLNK:\r
-               retNode.Flags = VFS_FFLAG_SYMLINK;\r
-               break;\r
-       // Regular File\r
-       case EXT2_S_IFREG:\r
-               retNode.Flags = 0;\r
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;\r
-               break;\r
-       // Directory\r
-       case EXT2_S_IFDIR:\r
-               retNode.ReadDir = Ext2_ReadDir;\r
-               retNode.FindDir = Ext2_FindDir;\r
-               retNode.MkNod = Ext2_MkNod;\r
-               //retNode.Relink = Ext2_Relink;\r
-               retNode.Flags = VFS_FFLAG_DIRECTORY;\r
-               break;\r
-       // Unknown, Write protect and hide it to be safe \r
-       default:\r
-               retNode.Flags = VFS_FFLAG_READONLY;//|VFS_FFLAG_HIDDEN;\r
-               break;\r
-       }\r
-       \r
-       // Check if the file should be hidden\r
-       //if(Name[0] == '.')    retNode.Flags |= VFS_FFLAG_HIDDEN;\r
-       \r
-       // Set Timestamps\r
-       retNode.ATime = now();\r
-       retNode.MTime = inode.i_mtime * 1000;\r
-       retNode.CTime = inode.i_ctime * 1000;\r
-       \r
-       // Save in node cache and return saved node\r
-       return Inode_CacheNode(Disk->CacheID, &retNode);\r
-}\r
-\r
-/**\r
- * \fn int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
- * \brief Read an inode into memory\r
- */\r
-int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
-{\r
-        int    group, subId;\r
-       \r
-       //LogF("Ext2_int_ReadInode: (Disk=%p, InodeId=%i, Inode=%p)", Disk, InodeId, Inode);\r
-       //ENTER("pDisk iInodeId pInode", Disk, InodeId, Inode);\r
-       \r
-       if(InodeId == 0)        return 0;\r
-       \r
-       InodeId --;     // Inodes are numbered starting at 1\r
-       \r
-       group = InodeId / Disk->SuperBlock.s_inodes_per_group;\r
-       subId = InodeId % Disk->SuperBlock.s_inodes_per_group;\r
-       \r
-       //LOG("group=%i, subId = %i", group, subId);\r
-       \r
-       // Read Inode\r
-       VFS_ReadAt(Disk->FD,\r
-               Disk->Groups[group].bg_inode_table * Disk->BlockSize + sizeof(tExt2_Inode)*subId,\r
-               sizeof(tExt2_Inode),\r
-               Inode);\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
- * \brief Get the address of a block from an inode's list\r
- * \param Disk Disk information structure\r
- * \param Blocks       Pointer to an inode's block list\r
- * \param BlockNum     Block index in list\r
- */\r
-Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
-{\r
-       Uint32  *iBlocks;\r
-       // Direct Blocks\r
-       if(BlockNum < 12)\r
-               return (Uint64)Blocks[BlockNum] * Disk->BlockSize;\r
-       \r
-       // Single Indirect Blocks\r
-       iBlocks = malloc( Disk->BlockSize );\r
-       VFS_ReadAt(Disk->FD, (Uint64)Blocks[12]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       \r
-       BlockNum -= 12;\r
-       if(BlockNum < 256) {\r
-               BlockNum = iBlocks[BlockNum];\r
-               free(iBlocks);\r
-               return (Uint64)BlockNum * Disk->BlockSize;\r
-       }\r
-       \r
-       // Double Indirect Blocks\r
-       if(BlockNum < 256*256)\r
-       {\r
-               VFS_ReadAt(Disk->FD, (Uint64)Blocks[13]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-               VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-               BlockNum = iBlocks[BlockNum%256];\r
-               free(iBlocks);\r
-               return (Uint64)BlockNum * Disk->BlockSize;\r
-       }\r
-       // Triple Indirect Blocks\r
-       VFS_ReadAt(Disk->FD, (Uint64)Blocks[14]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/(256*256)]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[(BlockNum/256)%256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
-       BlockNum = iBlocks[BlockNum%256];\r
-       free(iBlocks);\r
-       return (Uint64)BlockNum * Disk->BlockSize;\r
-}\r
-\r
-/**\r
- * \fn Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
- * \brief Allocate an inode (from the current group preferably)\r
- * \param Disk EXT2 Disk Information Structure\r
- * \param Parent       Inode ID of the parent (used to locate the child nearby)\r
- */\r
-Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
-{\r
-//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)\r
- * \brief Allocate a block from the best possible location\r
- * \param Disk EXT2 Disk Information Structure\r
- * \param PrevBlock    Previous block ID in the file\r
- */\r
-Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)\r
-{\r
-        int    bpg = Disk->SuperBlock.s_blocks_per_group;\r
-       Uint    blockgroup = PrevBlock / bpg;\r
-       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];\r
-       Uint    bitsperblock = 8*Disk->BlockSize;\r
-        int    i, j = 0;\r
-       Uint    block;\r
-       \r
-       // Are there any free blocks?\r
-       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;\r
-       \r
-       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)\r
-       {\r
-               // Search block group's bitmap\r
-               for(i = 0; i < bpg; i++)\r
-               {\r
-                       // Get the block in the bitmap block\r
-                       j = i & (bitsperblock-1);\r
-                       \r
-                       // Read in if needed\r
-                       if(j == 0) {\r
-                               VFS_ReadAt(\r
-                                       Disk->FD,\r
-                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,\r
-                                       Disk->BlockSize,\r
-                                       bitmap\r
-                                       );\r
-                       }\r
-                       \r
-                       // Fast Check\r
-                       if( bitmap[j/32] == -1 ) {\r
-                               j = (j + 31) & ~31;\r
-                               continue;\r
-                       }\r
-                       \r
-                       // Is the bit set?\r
-                       if( bitmap[j/32] & (1 << (j%32)) )\r
-                               continue;\r
-                       \r
-                       // Ooh! We found one\r
-                       break;\r
-               }\r
-               if( i < bpg ) {\r
-                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");\r
-                       goto    checkAll;       // Search the entire filesystem for a free block\r
-                       // Goto needed for neatness\r
-               }\r
-               \r
-               // Mark as used\r
-               bitmap[j/32] |= (1 << (j%32));\r
-               VFS_WriteAt(\r
-                       Disk->FD,\r
-                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,\r
-                       Disk->BlockSize,\r
-                       bitmap\r
-                       );\r
-               block = i;\r
-               Disk->Groups[blockgroup].bg_free_blocks_count --;\r
-       }\r
-       else\r
-       {\r
-       checkAll:\r
-               Warning("[EXT2 ] TODO - Implement using blocks outside the current block group");\r
-               return 0;\r
-       }\r
-       \r
-       // Reduce global count\r
-       Disk->SuperBlock.s_free_blocks_count --;\r
-       #if EXT2_UPDATE_WRITEBACK\r
-       Ext2_int_UpdateSuperblock(Disk);\r
-       #endif\r
-       \r
-       return block;\r
-}\r
-\r
-/**\r
- * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
- */\r
-void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
-{\r
-       VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
-}\r
diff --git a/Kernel/vfs/fs/fs_ext2.h b/Kernel/vfs/fs/fs_ext2.h
deleted file mode 100644 (file)
index f7c9ae1..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/**\r
- * Acess2\r
- * \file fs_ext2.h\r
- * \brief EXT2 Filesystem Driver\r
- */\r
-\r
-/**\r
- \name Inode Flag Values\r
- \{\r
-*/\r
-#define EXT2_S_IFMT            0xF000  //!< Format Mask\r
-#define EXT2_S_IFSOCK  0xC000  //!< Socket\r
-#define EXT2_S_IFLNK   0xA000  //!< Symbolic Link\r
-#define EXT2_S_IFREG   0x8000  //!< Regular File\r
-#define EXT2_S_IFBLK   0x6000  //!< Block Device\r
-#define EXT2_S_IFDIR   0x4000  //!< Directory\r
-#define EXT2_S_IFCHR   0x2000  //!< Character Device\r
-#define EXT2_S_IFIFO   0x1000  //!< FIFO\r
-#define EXT2_S_ISUID   0x0800  //!< SUID\r
-#define EXT2_S_ISGID   0x0400  //!< SGID\r
-#define EXT2_S_ISVTX   0x0200  //!< sticky bit\r
-#define EXT2_S_IRWXU   0700    //!< user access rights mask\r
-#define EXT2_S_IRUSR   0400    //!< Owner Read\r
-#define EXT2_S_IWUSR   0200    //!< Owner Write\r
-#define EXT2_S_IXUSR   0100    //!< Owner Execute\r
-#define EXT2_S_IRWXG   0070    //!< Group Access rights mask\r
-#define EXT2_S_IRGRP   0040    //!< Group Read\r
-#define EXT2_S_IWGRP   0020    //!< Group Write\r
-#define EXT2_S_IXGRP   0010    //!< Group Execute\r
-#define EXT2_S_IRWXO   0007    //!< Global Access rights mask\r
-#define EXT2_S_IROTH   0004    //!< Global Read\r
-#define EXT2_S_IWOTH   0002    //!< Global Write\r
-#define EXT2_S_IXOTH   0001    //!< Global Execute\r
-//! \}\r
-\r
-#define EXT2_NAME_LEN 255      //!< Maximum Name Length\r
-\r
-// === TYPEDEFS ===\r
-typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
-typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
-typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
-typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
-\r
-// === STRUCTURES ===\r
-/**\r
- * \brief EXT2 Superblock Structure\r
- */\r
-struct ext2_super_block_s {\r
-       Uint32  s_inodes_count;         //!< Inodes count\r
-       Uint32  s_blocks_count;         //!< Blocks count\r
-       Uint32  s_r_blocks_count;       //!< Reserved blocks count\r
-       Uint32  s_free_blocks_count;    //!< Free blocks count\r
-       Uint32  s_free_inodes_count;    //!< Free inodes count\r
-       Uint32  s_first_data_block;     //!< First Data Block\r
-       Uint32  s_log_block_size;       //!< Block size\r
-       Sint32  s_log_frag_size;        //!< Fragment size\r
-       Uint32  s_blocks_per_group;     //!< Number Blocks per group\r
-       Uint32  s_frags_per_group;      //!< Number Fragments per group\r
-       Uint32  s_inodes_per_group;     //!< Number Inodes per group\r
-       Uint32  s_mtime;                        //!< Mount time\r
-       Uint32  s_wtime;                        //!< Write time\r
-       Uint16  s_mnt_count;            //!< Mount count\r
-       Sint16  s_max_mnt_count;        //!< Maximal mount count\r
-       Uint16  s_magic;                        //!< Magic signature\r
-       Uint16  s_state;                        //!< File system state\r
-       Uint16  s_errors;                       //!< Behaviour when detecting errors\r
-       Uint16  s_pad;                          //!< Padding\r
-       Uint32  s_lastcheck;            //!< time of last check\r
-       Uint32  s_checkinterval;        //!< max. time between checks\r
-       Uint32  s_creator_os;           //!< Formatting OS\r
-       Uint32  s_rev_level;            //!< Revision level\r
-       Uint16  s_def_resuid;           //!< Default uid for reserved blocks\r
-       Uint16  s_def_resgid;           //!< Default gid for reserved blocks\r
-       Uint32  s_reserved[235];        //!< Padding to the end of the block\r
-};\r
-\r
-/**\r
- * \struct ext2_inode_s\r
- * \brief EXT2 Inode Definition\r
- */\r
-struct ext2_inode_s {\r
-       Uint16 i_mode;  //!< File mode\r
-       Uint16 i_uid;   //!< Owner Uid\r
-       Uint32 i_size;  //!< Size in bytes\r
-       Uint32 i_atime; //!< Access time\r
-       Uint32 i_ctime; //!< Creation time\r
-       Uint32 i_mtime; //!< Modification time\r
-       Uint32 i_dtime; //!< Deletion Time\r
-       Uint16 i_gid;   //!< Group Id\r
-       Uint16 i_links_count;   //!< Links count\r
-       Uint32 i_blocks;        //!< Blocks count\r
-       Uint32 i_flags; //!< File flags\r
-       union {\r
-               Uint32 linux_reserved1; //!< Linux: Reserved\r
-               Uint32 hurd_translator; //!< HURD: Translator\r
-               Uint32 masix_reserved1; //!< Masix: Reserved\r
-       } osd1; //!< OS dependent 1\r
-       Uint32 i_block[15];     //!< Pointers to blocks\r
-       Uint32 i_version;       //!< File version (for NFS)\r
-       Uint32 i_file_acl;      //!< File ACL\r
-       Uint32 i_dir_acl;       //!< Directory ACL / Extended File Size\r
-       Uint32 i_faddr;         //!< Fragment address\r
-       union {\r
-               struct {\r
-                       Uint8 l_i_frag; //!< Fragment number\r
-                       Uint8 l_i_fsize;        //!< Fragment size\r
-                       Uint16 i_pad1;  //!< Padding\r
-                       Uint32 l_i_reserved2[2];        //!< Reserved\r
-               } linux2;\r
-               struct {\r
-                       Uint8 h_i_frag; //!< Fragment number\r
-                       Uint8 h_i_fsize; //!< Fragment size\r
-                       Uint16 h_i_mode_high;   //!< Mode High Bits\r
-                       Uint16 h_i_uid_high;    //!< UID High Bits\r
-                       Uint16 h_i_gid_high;    //!< GID High Bits\r
-                       Uint32 h_i_author;      //!< Creator ID\r
-               } hurd2;\r
-               struct {\r
-                       Uint8 m_i_frag; //!< Fragment number\r
-                       Uint8 m_i_fsize;        //!< Fragment size\r
-                       Uint16 m_pad1;  //!< Padding\r
-                       Uint32 m_i_reserved2[2];        //!< reserved\r
-               } masix2;\r
-       } osd2; //!< OS dependent 2\r
-};\r
-\r
-/**\r
- * \struct ext2_group_desc_s\r
- * \brief EXT2 Group Descriptor\r
- */\r
-struct ext2_group_desc_s {\r
-       Uint32  bg_block_bitmap;        //!< Blocks bitmap block\r
-       Uint32  bg_inode_bitmap;        //!< Inodes bitmap block\r
-       Uint32  bg_inode_table; //!< Inodes table block\r
-       Uint16  bg_free_blocks_count;   //!< Free blocks count\r
-       Uint16  bg_free_inodes_count;   //!< Free inodes count\r
-       Uint16  bg_used_dirs_count;     //!< Directories count\r
-       Uint16  bg_pad; //!< Padding\r
-       Uint32  bg_reserved[3]; //!< Reserved\r
-};\r
-\r
-/**\r
- * \brief EXT2 Directory Entry\r
- * \note The name may take up less than 255 characters\r
- */\r
-struct ext2_dir_entry_s {\r
-       Uint32  inode;          //!< Inode number\r
-       Uint16  rec_len;        //!< Directory entry length\r
-       Uint8   name_len;       //!< Short Name Length\r
-       Uint8   type;           //!< File Type\r
-       char    name[];         //!< File name\r
-};\r
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..392ab5d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,39 @@
+#
+# Acess2 Core Makefile
+#
+
+.PHONY: all clean
+
+all:
+       @echo === Kernel
+       @$(MAKE) all --no-print-directory -C Kernel
+       @echo === ld-acess.so
+       @$(MAKE) all --no-print-directory -C Usermode/Libraries/ld-acess.so_src
+       @echo === libacess.so
+       @$(MAKE) all --no-print-directory -C Usermode/Libraries/libacess.so_src
+       @echo === libgcc.so
+       @$(MAKE) all --no-print-directory -C Usermode/Libraries/libgcc.so_src
+       @echo === libc.so
+       @$(MAKE) all --no-print-directory -C Usermode/Libraries/libc.so_src
+       @echo === init
+       @$(MAKE) all --no-print-directory -C Usermode/Applications/init_src
+       @echo === login
+       @$(MAKE) all --no-print-directory -C Usermode/Applications/login_src
+       @echo === CLIShell
+       @$(MAKE) all --no-print-directory -C Usermode/Applications/CLIShell_src
+       @echo === cat
+       @$(MAKE) all --no-print-directory -C Usermode/Applications/cat_src
+       @echo === ls
+       @$(MAKE) all --no-print-directory -C Usermode/Applications/ls_src
+
+clean:
+       make clean --no-print-directory -C Kernel/
+       make clean --no-print-directory -C Usermode/Libraries/ld-acess.so_src
+       make clean --no-print-directory -C Usermode/Libraries/libacess.so_src
+       make clean --no-print-directory -C Usermode/Libraries/libc.so_src
+       make clean --no-print-directory -C Usermode/Libraries/libgcc.so_src
+       make clean --no-print-directory -C Usermode/Applications/init_src
+       make clean --no-print-directory -C Usermode/Applications/login_src
+       make clean --no-print-directory -C Usermode/Applications/CLIShell_src
+       make clean --no-print-directory -C Usermode/Applications/cat_src
+       make clean --no-print-directory -C Usermode/Applications/ls_src
index a8d3b20..18181a9 100644 (file)
@@ -14,9 +14,9 @@ RMDIR = rm -rf
 ARCH = i386
 ARCHDIR = x86
 
-FILESYSTEMS = fat ext2
+FILESYSTEMS = fat
 DRIVERS = ata_x86
-MODULES = FDD NE2000 BochsVBE
+MODULES = FS_Ext2 FDD NE2000 BochsGA
 
 DISTROOT = /mnt/AcessHDD/Acess2
 ACESSDIR = /home/hodgeja/Projects/Acess2
diff --git a/Modules/BochsVBE/Makefile b/Modules/BochsVBE/Makefile
deleted file mode 100644 (file)
index add4018..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-#
-
-OBJ = bochsvbe.o
-NAME = BochsVBE
-
--include ../Makefile.tpl
diff --git a/Modules/BochsVBE/bochsvbe.c b/Modules/BochsVBE/bochsvbe.c
deleted file mode 100644 (file)
index 2fe0110..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/**\r
- * \file drv_bochsvbe.c\r
- * \brief BGA (Bochs Graphic Adapter) Driver\r
- * \note for Acess2\r
- * \warning This driver does NOT support the Bochs PCI VGA driver\r
-*/\r
-#define DEBUG  0\r
-#include <common.h>\r
-#include <errno.h>\r
-#include <modules.h>\r
-#include <vfs.h>\r
-#include <fs_devfs.h>\r
-#include <drv_pci.h>\r
-#include <tpl_drv_video.h>\r
-\r
-//#define INT  static\r
-#define INT\r
-\r
-// === TYPEDEFS ===\r
-typedef struct {\r
-       Uint16  width;\r
-       Uint16  height;\r
-       Uint16  bpp;\r
-       Uint16  flags;\r
-       Uint32  fbSize;\r
-} t_bga_mode;\r
-\r
-// === CONSTANTS ===\r
-enum eMode_Flags {\r
-       MODEFLAG_TEXT = 1\r
-};\r
-#define        BGA_LFB_MAXSIZE (1024*768*4)\r
-#define        VBE_DISPI_BANK_ADDRESS  0xA0000\r
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000\r
-#define VBE_DISPI_IOPORT_INDEX 0x01CE\r
-#define        VBE_DISPI_IOPORT_DATA   0x01CF\r
-#define        VBE_DISPI_DISABLED      0x00\r
-#define VBE_DISPI_ENABLED      0x01\r
-#define        VBE_DISPI_LFB_ENABLED   0x40\r
-#define        VBE_DISPI_NOCLEARMEM    0x80\r
-enum {\r
-       VBE_DISPI_INDEX_ID,\r
-       VBE_DISPI_INDEX_XRES,\r
-       VBE_DISPI_INDEX_YRES,\r
-       VBE_DISPI_INDEX_BPP,\r
-       VBE_DISPI_INDEX_ENABLE,\r
-       VBE_DISPI_INDEX_BANK,\r
-       VBE_DISPI_INDEX_VIRT_WIDTH,\r
-       VBE_DISPI_INDEX_VIRT_HEIGHT,\r
-       VBE_DISPI_INDEX_X_OFFSET,\r
-       VBE_DISPI_INDEX_Y_OFFSET\r
-};\r
-\r
-\r
-// === PROTOTYPES ===\r
-// Driver\r
- int   BGA_Install(char **Arguments);\r
-void   BGA_Uninstall();\r
-// Internal\r
-void   BGA_int_WriteRegister(Uint16 reg, Uint16 value);\r
-Uint16 BGA_int_ReadRegister(Uint16 reg);\r
-void   BGA_int_SetBank(Uint16 bank);\r
-void   BGA_int_SetMode(Uint16 width, Uint16 height);\r
- int   BGA_int_UpdateMode(int id);\r
- int   BGA_int_FindMode(tVideo_IOCtl_Mode *info);\r
- int   BGA_int_ModeInfo(tVideo_IOCtl_Mode *info);\r
- int   BGA_int_MapFB(void *Dest);\r
-// Filesystem\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);\r
- int   BGA_Ioctl(tVFS_Node *node, int id, void *data);\r
-\r
-// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x0032, BochsVBE, BGA_Install, NULL, NULL);\r
-tDevFS_Driver  gBGA_DriverStruct = {\r
-       NULL, "BochsGA",\r
-       {\r
-       .Read = BGA_Read,\r
-       .Write = BGA_Write,\r
-       .IOCtl = BGA_Ioctl\r
-       }\r
-};\r
- int   giBGA_CurrentMode = -1;\r
- int   giBGA_DriverId = -1;\r
-Uint   *gBGA_Framebuffer;\r
-t_bga_mode     gBGA_Modes[] = {\r
-       {},\r
-       { 80,25, 12, MODEFLAG_TEXT, 80*25*8},   // 640 x 480\r
-       {100,37, 12, MODEFLAG_TEXT, 100*37*8},  // 800 x 600\r
-       {640,480,8, 0, 640*480},\r
-       {640,480,32, 0, 640*480*4},\r
-       {800,600,8, 0, 800*600},\r
-       {800,600,32, 0, 800*600*4},\r
-};\r
-#define        BGA_MODE_COUNT  (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
-\r
-// === CODE ===\r
-/**\r
- * \fn int BGA_Install(char **Arguments)\r
- */\r
-int BGA_Install(char **Arguments)\r
-{\r
-        int    bga_version = 0;\r
-       \r
-       // Check BGA Version\r
-       bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
-       // NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable\r
-       if(bga_version < 0xB0C4 || bga_version > 0xB0C5) {\r
-               Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version);\r
-               return 0;\r
-       }\r
-       \r
-       // Install Device\r
-       giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct );\r
-       if(giBGA_DriverId == -1) {\r
-               Warning("[BGA ] Unable to register with DevFS, maybe already loaded?");\r
-               return 0;\r
-       }\r
-       \r
-       // Map Framebuffer to hardware address\r
-       gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768);  // 768 pages (3Mb)\r
-       \r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn void BGA_Uninstall()\r
- */\r
-void BGA_Uninstall()\r
-{\r
-       //DevFS_DelDevice( giBGA_DriverId );\r
-       MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Read from the framebuffer\r
- */\r
-Uint64 BGA_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{\r
-       // Check Mode\r
-       if(giBGA_CurrentMode == -1)     return -1;\r
-       \r
-       // Check Offset and Length against Framebuffer Size\r
-       if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize)\r
-               return -1;\r
-       \r
-       // Copy from Framebuffer\r
-       memcpy(buffer, (void*)((Uint)gBGA_Framebuffer + (Uint)off), len);\r
-       return len;\r
-}\r
-\r
-/**\r
- * \fn Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
- * \brief Write to the framebuffer\r
- */\r
-Uint64 BGA_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)\r
-{      \r
-       ENTER("xoff xlen", off, len);\r
-       \r
-       // Check Mode\r
-       if(giBGA_CurrentMode == -1) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       // Check Input against Frambuffer Size\r
-       if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize) {\r
-               LEAVE('i', -1);\r
-               return -1;\r
-       }\r
-       \r
-       // Text Mode\r
-       if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT )\r
-       {\r
-               tVT_Char        *chars = buffer;\r
-                int    pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
-               Uint32  *dest;\r
-               off /= sizeof(tVT_Char);\r
-               dest = (void*)gBGA_Framebuffer;\r
-               dest += (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight * pitch;\r
-               dest += (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth;\r
-               len /= sizeof(tVT_Char);\r
-               while(len--)\r
-               {\r
-                       VT_Font_Render(\r
-                               chars->Ch,\r
-                               dest, pitch,\r
-                               VT_Colour12to24(chars->BGCol),\r
-                               VT_Colour12to24(chars->FGCol)\r
-                               );\r
-                       dest += giVT_CharWidth;\r
-                       chars++;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               Uint8   *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off);\r
-               \r
-               LOG("buffer = %p\n", buffer);\r
-               LOG("Updating Framebuffer (%p to %p)\n", \r
-                       destBuf, destBuf + (Uint)len);\r
-               \r
-               \r
-               // Copy to Frambuffer\r
-               memcpy(destBuf, buffer, len);\r
-               \r
-               LOG("BGA Framebuffer updated\n");\r
-       }\r
-       \r
-       LEAVE('i', len);\r
-       return len;\r
-}\r
-\r
-/**\r
- * \fn INT int BGA_Ioctl(tVFS_Node *node, int id, void *data)\r
- * \brief Handle messages to the device\r
- */\r
-INT int BGA_Ioctl(tVFS_Node *node, int id, void *data)\r
-{\r
-        int    ret = -2;\r
-       ENTER("pNode iId pData", node, id, data);\r
-       \r
-       switch(id)\r
-       {\r
-       case DRV_IOCTL_TYPE:\r
-               ret = DRV_TYPE_VIDEO;\r
-               break;\r
-       case DRV_IOCTL_IDENT:\r
-               memcpy(data, "BGA1", 4);\r
-               ret = 1;\r
-               break;\r
-       case DRV_IOCTL_VERSION:\r
-               ret = 0x100;\r
-               break;\r
-       case DRV_IOCTL_LOOKUP:  // TODO: Implement\r
-               ret = 0;\r
-               break;\r
-               \r
-       case VIDEO_IOCTL_SETMODE:\r
-               ret = BGA_int_UpdateMode(*(int*)(data));\r
-               break;\r
-               \r
-       case VIDEO_IOCTL_GETMODE:\r
-               ret = giBGA_CurrentMode;\r
-               break;\r
-       \r
-       case VIDEO_IOCTL_FINDMODE:\r
-               ret = BGA_int_FindMode((tVideo_IOCtl_Mode*)data);\r
-               break;\r
-       \r
-       case VIDEO_IOCTL_MODEINFO:\r
-               ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)data);\r
-               break;\r
-       \r
-       // Request Access to LFB\r
-       case VIDEO_IOCTL_REQLFB:\r
-               ret = BGA_int_MapFB( *(void**)data );\r
-               break;\r
-       \r
-       default:\r
-               LEAVE('i', -2);\r
-               return -2;\r
-       }\r
-       \r
-       LEAVE('i', ret);\r
-       return ret;\r
-}\r
-\r
-//== Internal Functions ==\r
-/**\r
- * \fn void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
- * \brief Writes to a BGA register\r
- */\r
-void BGA_int_WriteRegister(Uint16 reg, Uint16 value)\r
-{\r
-       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
-       outw(VBE_DISPI_IOPORT_DATA, value);\r
-}\r
-\r
-INT Uint16 BGA_int_ReadRegister(Uint16 reg)\r
-{\r
-       outw(VBE_DISPI_IOPORT_INDEX, reg);\r
-       return inw(VBE_DISPI_IOPORT_DATA);\r
-}\r
-\r
-#if 0\r
-INT void BGA_int_SetBank(Uint16 bank)\r
-{\r
-       BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank);\r
-}\r
-#endif\r
-\r
-/**\r
- * \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp)\r
- * \brief Sets the video mode from the dimensions and bpp given\r
- */\r
-void BGA_int_SetMode(Uint16 width, Uint16 height)\r
-{\r
-       ENTER("iwidth iheight ibpp", width, height, bpp);\r
-       BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES,        width);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES,        height);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32);\r
-    BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED);\r
-    //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM);\r
-       LEAVE('-');\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_UpdateMode(int id)\r
- * \brief Set current vide mode given a mode id\r
- */\r
-int BGA_int_UpdateMode(int id)\r
-{\r
-       // Sanity Check\r
-       if(id < 0 || id >= BGA_MODE_COUNT)      return -1;\r
-       \r
-       // Check if it is a text mode\r
-       if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width*giVT_CharWidth,\r
-                       gBGA_Modes[id].height*giVT_CharHeight);\r
-       else    // Graphics?\r
-               BGA_int_SetMode(\r
-                       gBGA_Modes[id].width,\r
-                       gBGA_Modes[id].height);\r
-       \r
-       giBGA_CurrentMode = id;\r
-       return id;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
- * \brief Find a mode matching the given options\r
- */\r
-int BGA_int_FindMode(tVideo_IOCtl_Mode *info)\r
-{\r
-        int    i;\r
-        int    best = 0, bestFactor = 1000;\r
-        int    factor, tmp;\r
-        int    rqdProduct = info->width * info->height * info->bpp;\r
-       \r
-       ENTER("pinfo", info);\r
-       LOG("info = {width:%i,height:%i,bpp:%i})\n", info->width, info->height, info->bpp);\r
-       \r
-       for(i = 0; i < BGA_MODE_COUNT; i++)\r
-       {\r
-               #if DEBUG >= 2\r
-               LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
-               #endif\r
-               \r
-               // Check if this mode is the same type as what we want\r
-               if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) )\r
-                       continue;\r
-               \r
-               // Ooh! A perfect match\r
-               if(gBGA_Modes[i].width == info->width\r
-               && gBGA_Modes[i].height == info->height\r
-               && gBGA_Modes[i].bpp == info->bpp)\r
-               {\r
-                       #if DEBUG >= 2\r
-                       LogF("Perfect!\n");\r
-                       #endif\r
-                       best = i;\r
-                       break;\r
-               }\r
-               \r
-               // If not, how close are we?\r
-               tmp = gBGA_Modes[i].width * gBGA_Modes[i].height * gBGA_Modes[i].bpp;\r
-               tmp -= rqdProduct;\r
-               tmp = tmp < 0 ? -tmp : tmp;     // tmp = ABS(tmp)\r
-               factor = tmp * 100 / rqdProduct;\r
-               \r
-               #if DEBUG >= 2\r
-               LogF("factor = %i\n", factor);\r
-               #endif\r
-               \r
-               if(factor < bestFactor)\r
-               {\r
-                       bestFactor = factor;\r
-                       best = i;\r
-               }\r
-       }\r
-       \r
-       info->id = best;\r
-       info->width = gBGA_Modes[best].width;\r
-       info->height = gBGA_Modes[best].height;\r
-       info->bpp = gBGA_Modes[best].bpp;\r
-       \r
-       info->flags = 0;\r
-       if(gBGA_Modes[best].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
-       return best;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
- * \brief Get mode information\r
- */\r
-int BGA_int_ModeInfo(tVideo_IOCtl_Mode *info)\r
-{\r
-       // Sanity Check\r
-       //if( !MM_IsUser( (Uint)info, sizeof(tVideo_IOCtl_Mode) ) ) {\r
-       //      return -EINVAL;\r
-       //}\r
-       \r
-       if(info->id < 0 || info->id >= BGA_MODE_COUNT)  return -1;\r
-       \r
-       info->width = gBGA_Modes[info->id].width;\r
-       info->height = gBGA_Modes[info->id].height;\r
-       info->bpp = gBGA_Modes[info->id].bpp;\r
-       \r
-       info->flags = 0;\r
-       if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT)\r
-               info->flags |= VIDEO_FLAG_TEXT;\r
-       \r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int BGA_int_MapFB(void *Dest)\r
- * \brief Map the framebuffer into a process's space\r
- * \param Dest User address to load to\r
- */\r
-int BGA_int_MapFB(void *Dest)\r
-{\r
-       Uint    i;\r
-       Uint    pages;\r
-       \r
-       // Sanity Check\r
-       if((Uint)Dest > 0xC0000000)     return 0;\r
-       if(gBGA_Modes[giBGA_CurrentMode].bpp < 15)      return 0;       // Only non-pallete modes are supported\r
-       \r
-       // Count required pages\r
-       pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12;\r
-       \r
-       // Check if there is space\r
-       for( i = 0; i < pages; i++ )\r
-       {\r
-               if(MM_GetPhysAddr( (Uint)Dest + (i << 12) ))\r
-                       return 0;\r
-       }\r
-       \r
-       // Map\r
-       for( i = 0; i < pages; i++ )\r
-               MM_Map( (Uint)Dest + (i<<12), VBE_DISPI_LFB_PHYSICAL_ADDRESS + (i<<12) );\r
-       \r
-       return 1;\r
-}\r
diff --git a/Modules/FS_Ext2/Makefile b/Modules/FS_Ext2/Makefile
new file mode 100644 (file)
index 0000000..806e638
--- /dev/null
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = ext2.o read.o dir.o write.o
+NAME = FS_Ext2
+
+-include ../Makefile.tpl
diff --git a/Modules/FS_Ext2/dir.c b/Modules/FS_Ext2/dir.c
new file mode 100644 (file)
index 0000000..5fe8933
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file dir.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+
+// === PROTOTYPES ===
+char           *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, char *FileName);
+ int           Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
+tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name);
+
+// === CODE ===
+/**
+ \fn char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+ \brief Reads a directory entry
+*/
+char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+{
+       tExt2_Inode     inode;
+       char    namebuf[EXT2_NAME_LEN+1];
+       tExt2_DirEnt    dirent;
+       Uint64  Base;   // Block's Base Address
+        int    block = 0, ofs = 0;
+        int    entNum = 0;
+       tExt2_Disk      *disk = Node->ImplPtr;
+       Uint    size;
+       
+       ENTER("pNode iPos", Node, Pos);
+       
+       // Read directory's inode
+       Ext2_int_GetInode(Node, &inode);
+       size = inode.i_size;
+       
+       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
+       
+       // Find Entry
+       // Get First Block
+       // - Do this ourselves as it is a simple operation
+       Base = inode.i_block[0] * disk->BlockSize;
+       while(Pos -- && size > 0)
+       {
+               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
+               ofs += dirent.rec_len;
+               size -= dirent.rec_len;
+               entNum ++;
+               
+               if(ofs >= disk->BlockSize) {
+                       block ++;
+                       if( ofs > disk->BlockSize ) {
+                               Warning("[EXT2] Directory Entry %i of inode %i extends over a block boundary, ignoring",
+                                       entNum-1, Node->Inode);
+                       }
+                       ofs = 0;
+                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+               }
+       }
+       
+       // Check for the end of the list
+       if(size <= 0) {
+               LEAVE('n');
+               return NULL;
+       }
+       
+       // Read Entry
+       VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
+       //LOG("dirent.inode = %i", dirent.inode);
+       //LOG("dirent.rec_len = %i", dirent.rec_len);
+       //LOG("dirent.name_len = %i", dirent.name_len);
+       VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
+       namebuf[ dirent.name_len ] = '\0';      // Cap off string
+       
+       
+       // Ignore . and .. (these are done in the VFS)
+       if( (namebuf[0] == '.' && namebuf[1] == '\0')
+       ||  (namebuf[0] == '.' && namebuf[1] == '.' && namebuf[2]=='\0')) {
+               LEAVE('p', VFS_SKIP);
+               return VFS_SKIP;        // Skip
+       }
+       
+       LEAVE('s', namebuf);
+       // Create new node
+       return strdup(namebuf);
+}
+
+/**
+ \fn tVFS_Node *Ext2_FindDir(tVFS_Node *node, char *filename)
+ \brief Gets information about a file
+ \param node   vfs node - Parent Node
+ \param filename       String - Name of file
+ \return VFS Node of file
+*/
+tVFS_Node *Ext2_FindDir(tVFS_Node *Node, char *Filename)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       char    namebuf[EXT2_NAME_LEN+1];
+       tExt2_DirEnt    dirent;
+       Uint64  Base;   // Block's Base Address
+        int    block = 0, ofs = 0;
+        int    entNum = 0;
+       Uint    size;
+       
+       // Read directory's inode
+       Ext2_int_GetInode(Node, &inode);
+       size = inode.i_size;
+       
+       // Get First Block
+       // - Do this ourselves as it is a simple operation
+       Base = inode.i_block[0] * disk->BlockSize;
+       // Find File
+       while(size > 0)
+       {
+               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
+               VFS_ReadAt( disk->FD, Base+ofs+sizeof(tExt2_DirEnt), dirent.name_len, namebuf );
+               namebuf[ dirent.name_len ] = '\0';      // Cap off string
+               // If it matches, create a node and return it
+               if(strcmp(namebuf, Filename) == 0)
+                       return Ext2_int_CreateNode( disk, dirent.inode, namebuf );
+               // Increment pointers
+               ofs += dirent.rec_len;
+               size -= dirent.rec_len;
+               entNum ++;
+               
+               // Check for end of block
+               if(ofs >= disk->BlockSize) {
+                       block ++;
+                       if( ofs > disk->BlockSize ) {
+                               Warning("[EXT2 ] Directory Entry %i of inode %i extends over a block boundary, ignoring",
+                                       entNum-1, Node->Inode);
+                       }
+                       ofs = 0;
+                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
+               }
+       }
+       
+       return NULL;
+}
+
+/**
+ * \fn int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
+ * \brief Create a new node
+ */
+int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
+{
+       return 0;
+}
+
+// ---- INTERNAL FUNCTIONS ----
+/**
+ * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
+ * \brief Create a new VFS Node
+ */
+tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID, char *Name)
+{
+       tExt2_Inode     inode;
+       tVFS_Node       retNode;
+       tVFS_Node       *tmpNode;
+       
+       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
+               return NULL;
+       
+       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
+               return tmpNode;
+       
+       
+       // Set identifiers
+       retNode.Inode = InodeID;
+       retNode.ImplPtr = Disk;
+       
+       // Set file length
+       retNode.Size = inode.i_size;
+       
+       // Set Access Permissions
+       retNode.UID = inode.i_uid;
+       retNode.GID = inode.i_gid;
+       retNode.NumACLs = 3;
+       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
+       
+       //  Set Function Pointers
+       retNode.Read = Ext2_Read;
+       retNode.Write = Ext2_Write;
+       retNode.Close = Ext2_CloseFile;
+       
+       switch(inode.i_mode & EXT2_S_IFMT)
+       {
+       // Symbolic Link
+       case EXT2_S_IFLNK:
+               retNode.Flags = VFS_FFLAG_SYMLINK;
+               break;
+       // Regular File
+       case EXT2_S_IFREG:
+               retNode.Flags = 0;
+               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
+               break;
+       // Directory
+       case EXT2_S_IFDIR:
+               retNode.ReadDir = Ext2_ReadDir;
+               retNode.FindDir = Ext2_FindDir;
+               retNode.MkNod = Ext2_MkNod;
+               //retNode.Relink = Ext2_Relink;
+               retNode.Flags = VFS_FFLAG_DIRECTORY;
+               break;
+       // Unknown, Write protect and hide it to be safe 
+       default:
+               retNode.Flags = VFS_FFLAG_READONLY;//|VFS_FFLAG_HIDDEN;
+               break;
+       }
+       
+       // Check if the file should be hidden
+       //if(Name[0] == '.')    retNode.Flags |= VFS_FFLAG_HIDDEN;
+       
+       // Set Timestamps
+       retNode.ATime = now();
+       retNode.MTime = inode.i_mtime * 1000;
+       retNode.CTime = inode.i_ctime * 1000;
+       
+       // Save in node cache and return saved node
+       return Inode_CacheNode(Disk->CacheID, &retNode);
+}
diff --git a/Modules/FS_Ext2/ext2.c b/Modules/FS_Ext2/ext2.c
new file mode 100644 (file)
index 0000000..81dcef0
--- /dev/null
@@ -0,0 +1,309 @@
+/*\r
+ * Acess OS\r
+ * Ext2 Driver Version 1\r
+ */\r
+/**\r
+ * \file fs/ext2.c\r
+ * \brief Second Extended Filesystem Driver\r
+ * \todo Implement file full write support\r
+ */\r
+#define DEBUG  1\r
+#define VERBOSE        0\r
+#include "ext2_common.h"\r
+#include <modules.h>\r
+\r
+// === PROTOTYPES ===\r
+ int   Ext2_Install(char **Arguments);\r
+// Interface Functions\r
+tVFS_Node      *Ext2_InitDevice(char *Device, char **Options);\r
+void           Ext2_Unmount(tVFS_Node *Node);\r
+void           Ext2_CloseFile(tVFS_Node *Node);\r
+// Internal Helpers\r
+ int           Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);\r
+Uint64         Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);\r
+Uint32         Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent);\r
+void           Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);\r
+\r
+// === SEMI-GLOBALS ===\r
+MODULE_DEFINE(0, 0x5B /*v0.90*/, FS_Ext2, Ext2_Install, NULL);\r
+tExt2_Disk     gExt2_disks[6];\r
+ int   giExt2_count = 0;\r
+tVFS_Driver    gExt2_FSInfo = {\r
+       "ext2", 0, Ext2_InitDevice, Ext2_Unmount, NULL\r
+       };\r
+\r
+// === CODE ===\r
+\r
+/**\r
+ * \fn int Ext2_Install(char **Arguments)\r
+ * \brief Install the Ext2 Filesystem Driver\r
+ */\r
+int Ext2_Install(char **Arguments)\r
+{\r
+       VFS_AddDriver( &gExt2_FSInfo );\r
+       return 1;\r
+}\r
+\r
+/**\r
+ \fn tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
+ \brief Initializes a device to be read by by the driver\r
+ \param Device String - Device to read from\r
+ \param Options        NULL Terminated array of option strings\r
+ \return Root Node\r
+*/\r
+tVFS_Node *Ext2_InitDevice(char *Device, char **Options)\r
+{\r
+       tExt2_Disk      *disk;\r
+        int    fd;\r
+        int    groupCount;\r
+       tExt2_SuperBlock        sb;\r
+       tExt2_Inode     inode;\r
+       \r
+       ENTER("sDevice pOptions", Device, Options);\r
+       \r
+       // Open Disk\r
+       fd = VFS_Open(Device, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);            //Open Device\r
+       if(fd == -1) {\r
+               Warning("[EXT2 ] Unable to open '%s'", Device);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Read Superblock at offset 1024\r
+       VFS_ReadAt(fd, 1024, 1024, &sb);        // Read Superblock\r
+       \r
+       // Sanity Check Magic value\r
+       if(sb.s_magic != 0xEF53) {\r
+               Warning("[EXT2 ] Volume '%s' is not an EXT2 volume", Device);\r
+               VFS_Close(fd);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       \r
+       // Get Group count\r
+       groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
+       LOG("groupCount = %i", groupCount);\r
+       \r
+       // Allocate Disk Information\r
+       disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\r
+       if(!disk) {\r
+               Warning("[EXT2 ] Unable to allocate disk structure");\r
+               VFS_Close(fd);\r
+               LEAVE('n');\r
+               return NULL;\r
+       }\r
+       disk->FD = fd;\r
+       memcpy(&disk->SuperBlock, &sb, 1024);\r
+       disk->GroupCount = groupCount;\r
+       \r
+       // Get an inode cache handle\r
+       disk->CacheID = Inode_GetHandle();\r
+       \r
+       // Get Block Size\r
+       LOG("s_log_block_size = 0x%x", sb.s_log_block_size);\r
+       disk->BlockSize = 1024 << sb.s_log_block_size;\r
+       \r
+       // Read Group Information\r
+       VFS_ReadAt(\r
+               disk->FD,\r
+               sb.s_first_data_block * disk->BlockSize + 1024,\r
+               sizeof(tExt2_Group)*groupCount,\r
+               disk->Groups\r
+               );\r
+       \r
+       #if VERBOSE\r
+       LOG("Block Group 0");\r
+       LOG(".bg_block_bitmap = 0x%x", disk->Groups[0].bg_block_bitmap);\r
+       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[0].bg_inode_bitmap);\r
+       LOG(".bg_inode_table = 0x%x", disk->Groups[0].bg_inode_table);\r
+       LOG("Block Group 1");\r
+       LOG(".bg_block_bitmap = 0x%x", disk->Groups[1].bg_block_bitmap);\r
+       LOG(".bg_inode_bitmap = 0x%x", disk->Groups[1].bg_inode_bitmap);\r
+       LOG(".bg_inode_table = 0x%x", disk->Groups[1].bg_inode_table);\r
+       #endif\r
+       \r
+       // Get root Inode\r
+       Ext2_int_ReadInode(disk, 2, &inode);\r
+       \r
+       // Create Root Node\r
+       memset(&disk->RootNode, 0, sizeof(tVFS_Node));\r
+       disk->RootNode.Inode = 2;       // Root inode ID\r
+       disk->RootNode.ImplPtr = disk;  // Save disk pointer\r
+       disk->RootNode.Size = -1;       // Fill in later (on readdir)\r
+       disk->RootNode.Flags = VFS_FFLAG_DIRECTORY;\r
+       \r
+       disk->RootNode.ReadDir = Ext2_ReadDir;\r
+       disk->RootNode.FindDir = Ext2_FindDir;\r
+       //disk->RootNode.Relink = Ext2_Relink;\r
+       \r
+       // Complete root node\r
+       disk->RootNode.UID = inode.i_uid;\r
+       disk->RootNode.GID = inode.i_gid;\r
+       disk->RootNode.NumACLs = 1;\r
+       disk->RootNode.ACLs = &gVFS_ACL_EveryoneRW;\r
+       \r
+       #if DEBUG\r
+       LOG("inode.i_size = 0x%x", inode.i_size);\r
+       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);\r
+       #endif\r
+       \r
+       LEAVE('p', &disk->RootNode);\r
+       return &disk->RootNode;\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_Unmount(tVFS_Node *Node)\r
+ * \brief Close a mounted device\r
+ */\r
+void Ext2_Unmount(tVFS_Node *Node)\r
+{\r
+       tExt2_Disk      *disk = Node->ImplPtr;\r
+       \r
+       VFS_Close( disk->FD );\r
+       Inode_ClearCache( disk->CacheID );\r
+       memset(disk, 0, sizeof(tExt2_Disk)+disk->GroupCount*sizeof(tExt2_Group));\r
+       free(disk);\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_CloseFile(tVFS_Node *Node)\r
+ * \brief Close a file (Remove it from the cache)\r
+ */\r
+void Ext2_CloseFile(tVFS_Node *Node)\r
+{\r
+       tExt2_Disk      *disk = Node->ImplPtr;\r
+       Inode_UncacheNode(disk->CacheID, Node->Inode);\r
+       return ;\r
+}\r
+\r
+//==================================\r
+//=       INTERNAL FUNCTIONS       =\r
+//==================================\r
+\r
+\r
+/**\r
+ * \fn int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
+ * \brief Gets the inode descriptor for a node\r
+ * \param Node node to get the Inode of\r
+ * \param Inode        Destination\r
+ */\r
+int Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode)\r
+{\r
+       return Ext2_int_ReadInode(Node->ImplPtr, Node->Inode, Inode);\r
+}\r
+\r
+/**\r
+ * \fn int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
+ * \brief Read an inode into memory\r
+ */\r
+int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode)\r
+{\r
+        int    group, subId;\r
+       \r
+       //LogF("Ext2_int_ReadInode: (Disk=%p, InodeId=%i, Inode=%p)", Disk, InodeId, Inode);\r
+       //ENTER("pDisk iInodeId pInode", Disk, InodeId, Inode);\r
+       \r
+       if(InodeId == 0)        return 0;\r
+       \r
+       InodeId --;     // Inodes are numbered starting at 1\r
+       \r
+       group = InodeId / Disk->SuperBlock.s_inodes_per_group;\r
+       subId = InodeId % Disk->SuperBlock.s_inodes_per_group;\r
+       \r
+       //LOG("group=%i, subId = %i", group, subId);\r
+       \r
+       // Read Inode\r
+       VFS_ReadAt(Disk->FD,\r
+               Disk->Groups[group].bg_inode_table * Disk->BlockSize + sizeof(tExt2_Inode)*subId,\r
+               sizeof(tExt2_Inode),\r
+               Inode);\r
+       return 1;\r
+}\r
+\r
+/**\r
+ * \fn Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
+ * \brief Get the address of a block from an inode's list\r
+ * \param Disk Disk information structure\r
+ * \param Blocks       Pointer to an inode's block list\r
+ * \param BlockNum     Block index in list\r
+ */\r
+Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)\r
+{\r
+       Uint32  *iBlocks;\r
+       // Direct Blocks\r
+       if(BlockNum < 12)\r
+               return (Uint64)Blocks[BlockNum] * Disk->BlockSize;\r
+       \r
+       // Single Indirect Blocks\r
+       iBlocks = malloc( Disk->BlockSize );\r
+       VFS_ReadAt(Disk->FD, (Uint64)Blocks[12]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       \r
+       BlockNum -= 12;\r
+       if(BlockNum < 256) {\r
+               BlockNum = iBlocks[BlockNum];\r
+               free(iBlocks);\r
+               return (Uint64)BlockNum * Disk->BlockSize;\r
+       }\r
+       \r
+       // Double Indirect Blocks\r
+       if(BlockNum < 256*256)\r
+       {\r
+               VFS_ReadAt(Disk->FD, (Uint64)Blocks[13]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+               VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+               BlockNum = iBlocks[BlockNum%256];\r
+               free(iBlocks);\r
+               return (Uint64)BlockNum * Disk->BlockSize;\r
+       }\r
+       // Triple Indirect Blocks\r
+       VFS_ReadAt(Disk->FD, (Uint64)Blocks[14]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[BlockNum/(256*256)]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       VFS_ReadAt(Disk->FD, (Uint64)iBlocks[(BlockNum/256)%256]*Disk->BlockSize, Disk->BlockSize, iBlocks);\r
+       BlockNum = iBlocks[BlockNum%256];\r
+       free(iBlocks);\r
+       return (Uint64)BlockNum * Disk->BlockSize;\r
+}\r
+\r
+/**\r
+ * \fn Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+ * \brief Allocate an inode (from the current group preferably)\r
+ * \param Disk EXT2 Disk Information Structure\r
+ * \param Parent       Inode ID of the parent (used to locate the child nearby)\r
+ */\r
+Uint32 Ext2_int_AllocateInode(tExt2_Disk *Disk, Uint32 Parent)\r
+{\r
+//     Uint    block = (Parent - 1) / Disk->SuperBlock.s_inodes_per_group;\r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+ * \brief Updates the superblock\r
+ */\r
+void Ext2_int_UpdateSuperblock(tExt2_Disk *Disk)\r
+{\r
+        int    bpg = Disk->SuperBlock.s_blocks_per_group;\r
+        int    ngrp = Disk->SuperBlock.s_blocks_count / bpg;\r
+        int    i;\r
+        \r
+       // Update Primary\r
+       VFS_WriteAt(Disk->FD, 1024, 1024, &Disk->SuperBlock);\r
+       \r
+       // Secondaries\r
+       // at Block Group 1, 3^n, 5^n, 7^n\r
+       \r
+       // 1\r
+       if(ngrp <= 1)   return;\r
+       VFS_WriteAt(Disk->FD, 1*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 3\r
+       for( i = 3; i < ngrp; i *= 3 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 5\r
+       for( i = 5; i < ngrp; i *= 5 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+       \r
+       // Powers of 7\r
+       for( i = 7; i < ngrp; i *= 7 )\r
+               VFS_WriteAt(Disk->FD, i*bpg*Disk->BlockSize, 1024, &Disk->SuperBlock);\r
+}\r
diff --git a/Modules/FS_Ext2/ext2_common.h b/Modules/FS_Ext2/ext2_common.h
new file mode 100644 (file)
index 0000000..07e838e
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file ext2_common.h
+ * \brief Second Extended Filesystem Driver
+ */
+#ifndef _EXT2_COMMON_H
+#define _EXT2_COMMON_H
+#include <common.h>
+#include <vfs.h>
+#include "ext2fs.h"
+
+#define EXT2_UPDATE_WRITEBACK  1
+
+// === STRUCTURES ===
+typedef struct {
+        int    FD;
+        int    CacheID;
+       tVFS_Node       RootNode;
+       
+       tExt2_SuperBlock        SuperBlock;
+        int    BlockSize;
+        
+        int    GroupCount;
+       tExt2_Group             Groups[];
+} tExt2_Disk;
+
+// === FUNCTIONS ===
+// --- Common ---
+extern void    Ext2_CloseFile(tVFS_Node *Node);
+extern int     Ext2_int_GetInode(tVFS_Node *Node, tExt2_Inode *Inode);
+extern Uint64  Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum);
+extern void    Ext2_int_UpdateSuperblock(tExt2_Disk *Disk);
+// --- Dir ---
+extern char    *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+extern tVFS_Node       *Ext2_FindDir(tVFS_Node *Node, char *FileName);
+extern int     Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);
+// --- Read ---
+extern Uint64  Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+extern int     Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
+// --- Write ---
+extern Uint64  Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+
+#endif
diff --git a/Modules/FS_Ext2/ext2fs.h b/Modules/FS_Ext2/ext2fs.h
new file mode 100644 (file)
index 0000000..8fd87ce
--- /dev/null
@@ -0,0 +1,156 @@
+/**\r
+ * Acess2\r
+ * \file ext2fs.h\r
+ * \brief EXT2 Filesystem Driver\r
+ */\r
+#ifndef _EXT2FS_H_\r
+#define _EXT2FS_H_\r
+\r
+/**\r
+ \name Inode Flag Values\r
+ \{\r
+*/\r
+#define EXT2_S_IFMT            0xF000  //!< Format Mask\r
+#define EXT2_S_IFSOCK  0xC000  //!< Socket\r
+#define EXT2_S_IFLNK   0xA000  //!< Symbolic Link\r
+#define EXT2_S_IFREG   0x8000  //!< Regular File\r
+#define EXT2_S_IFBLK   0x6000  //!< Block Device\r
+#define EXT2_S_IFDIR   0x4000  //!< Directory\r
+#define EXT2_S_IFCHR   0x2000  //!< Character Device\r
+#define EXT2_S_IFIFO   0x1000  //!< FIFO\r
+#define EXT2_S_ISUID   0x0800  //!< SUID\r
+#define EXT2_S_ISGID   0x0400  //!< SGID\r
+#define EXT2_S_ISVTX   0x0200  //!< sticky bit\r
+#define EXT2_S_IRWXU   0700    //!< user access rights mask\r
+#define EXT2_S_IRUSR   0400    //!< Owner Read\r
+#define EXT2_S_IWUSR   0200    //!< Owner Write\r
+#define EXT2_S_IXUSR   0100    //!< Owner Execute\r
+#define EXT2_S_IRWXG   0070    //!< Group Access rights mask\r
+#define EXT2_S_IRGRP   0040    //!< Group Read\r
+#define EXT2_S_IWGRP   0020    //!< Group Write\r
+#define EXT2_S_IXGRP   0010    //!< Group Execute\r
+#define EXT2_S_IRWXO   0007    //!< Global Access rights mask\r
+#define EXT2_S_IROTH   0004    //!< Global Read\r
+#define EXT2_S_IWOTH   0002    //!< Global Write\r
+#define EXT2_S_IXOTH   0001    //!< Global Execute\r
+//! \}\r
+\r
+#define EXT2_NAME_LEN 255      //!< Maximum Name Length\r
+\r
+// === TYPEDEFS ===\r
+typedef struct ext2_inode_s                    tExt2_Inode;    //!< Inode Type\r
+typedef struct ext2_super_block_s      tExt2_SuperBlock;       //!< Superblock Type\r
+typedef struct ext2_group_desc_s       tExt2_Group;    //!< Group Descriptor Type\r
+typedef struct ext2_dir_entry_s                tExt2_DirEnt;   //!< Directory Entry Type\r
+\r
+// === STRUCTURES ===\r
+/**\r
+ * \brief EXT2 Superblock Structure\r
+ */\r
+struct ext2_super_block_s {\r
+       Uint32  s_inodes_count;         //!< Inodes count\r
+       Uint32  s_blocks_count;         //!< Blocks count\r
+       Uint32  s_r_blocks_count;       //!< Reserved blocks count\r
+       Uint32  s_free_blocks_count;    //!< Free blocks count\r
+       Uint32  s_free_inodes_count;    //!< Free inodes count\r
+       Uint32  s_first_data_block;     //!< First Data Block\r
+       Uint32  s_log_block_size;       //!< Block size\r
+       Sint32  s_log_frag_size;        //!< Fragment size\r
+       Uint32  s_blocks_per_group;     //!< Number Blocks per group\r
+       Uint32  s_frags_per_group;      //!< Number Fragments per group\r
+       Uint32  s_inodes_per_group;     //!< Number Inodes per group\r
+       Uint32  s_mtime;                        //!< Mount time\r
+       Uint32  s_wtime;                        //!< Write time\r
+       Uint16  s_mnt_count;            //!< Mount count\r
+       Sint16  s_max_mnt_count;        //!< Maximal mount count\r
+       Uint16  s_magic;                        //!< Magic signature\r
+       Uint16  s_state;                        //!< File system state\r
+       Uint16  s_errors;                       //!< Behaviour when detecting errors\r
+       Uint16  s_pad;                          //!< Padding\r
+       Uint32  s_lastcheck;            //!< time of last check\r
+       Uint32  s_checkinterval;        //!< max. time between checks\r
+       Uint32  s_creator_os;           //!< Formatting OS\r
+       Uint32  s_rev_level;            //!< Revision level\r
+       Uint16  s_def_resuid;           //!< Default uid for reserved blocks\r
+       Uint16  s_def_resgid;           //!< Default gid for reserved blocks\r
+       Uint32  s_reserved[235];        //!< Padding to the end of the block\r
+};\r
+\r
+/**\r
+ * \struct ext2_inode_s\r
+ * \brief EXT2 Inode Definition\r
+ */\r
+struct ext2_inode_s {\r
+       Uint16 i_mode;  //!< File mode\r
+       Uint16 i_uid;   //!< Owner Uid\r
+       Uint32 i_size;  //!< Size in bytes\r
+       Uint32 i_atime; //!< Access time\r
+       Uint32 i_ctime; //!< Creation time\r
+       Uint32 i_mtime; //!< Modification time\r
+       Uint32 i_dtime; //!< Deletion Time\r
+       Uint16 i_gid;   //!< Group Id\r
+       Uint16 i_links_count;   //!< Links count\r
+       Uint32 i_blocks;        //!< Number of blocks allocated for the file\r
+       Uint32 i_flags; //!< File flags\r
+       union {\r
+               Uint32 linux_reserved1; //!< Linux: Reserved\r
+               Uint32 hurd_translator; //!< HURD: Translator\r
+               Uint32 masix_reserved1; //!< Masix: Reserved\r
+       } osd1; //!< OS dependent 1\r
+       Uint32 i_block[15];     //!< Pointers to blocks\r
+       Uint32 i_version;       //!< File version (for NFS)\r
+       Uint32 i_file_acl;      //!< File ACL\r
+       Uint32 i_dir_acl;       //!< Directory ACL / Extended File Size\r
+       Uint32 i_faddr;         //!< Fragment address\r
+       union {\r
+               struct {\r
+                       Uint8 l_i_frag; //!< Fragment number\r
+                       Uint8 l_i_fsize;        //!< Fragment size\r
+                       Uint16 i_pad1;  //!< Padding\r
+                       Uint32 l_i_reserved2[2];        //!< Reserved\r
+               } linux2;\r
+               struct {\r
+                       Uint8 h_i_frag; //!< Fragment number\r
+                       Uint8 h_i_fsize; //!< Fragment size\r
+                       Uint16 h_i_mode_high;   //!< Mode High Bits\r
+                       Uint16 h_i_uid_high;    //!< UID High Bits\r
+                       Uint16 h_i_gid_high;    //!< GID High Bits\r
+                       Uint32 h_i_author;      //!< Creator ID\r
+               } hurd2;\r
+               struct {\r
+                       Uint8 m_i_frag; //!< Fragment number\r
+                       Uint8 m_i_fsize;        //!< Fragment size\r
+                       Uint16 m_pad1;  //!< Padding\r
+                       Uint32 m_i_reserved2[2];        //!< reserved\r
+               } masix2;\r
+       } osd2; //!< OS dependent 2\r
+};\r
+\r
+/**\r
+ * \struct ext2_group_desc_s\r
+ * \brief EXT2 Group Descriptor\r
+ */\r
+struct ext2_group_desc_s {\r
+       Uint32  bg_block_bitmap;        //!< Blocks bitmap block\r
+       Uint32  bg_inode_bitmap;        //!< Inodes bitmap block\r
+       Uint32  bg_inode_table; //!< Inodes table block\r
+       Uint16  bg_free_blocks_count;   //!< Free blocks count\r
+       Uint16  bg_free_inodes_count;   //!< Free inodes count\r
+       Uint16  bg_used_dirs_count;     //!< Directories count\r
+       Uint16  bg_pad; //!< Padding\r
+       Uint32  bg_reserved[3]; //!< Reserved\r
+};\r
+\r
+/**\r
+ * \brief EXT2 Directory Entry\r
+ * \note The name may take up less than 255 characters\r
+ */\r
+struct ext2_dir_entry_s {\r
+       Uint32  inode;          //!< Inode number\r
+       Uint16  rec_len;        //!< Directory entry length\r
+       Uint8   name_len;       //!< Short Name Length\r
+       Uint8   type;           //!< File Type\r
+       char    name[];         //!< File name\r
+};\r
+\r
+#endif\r
diff --git a/Modules/FS_Ext2/read.c b/Modules/FS_Ext2/read.c
new file mode 100644 (file)
index 0000000..cb6649a
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file read.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+// === PROTOTYPES ===
+Uint64         Ext2_Read(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+ int           Ext2_int_ReadInode(tExt2_Disk *Disk, Uint InodeId, tExt2_Inode *Inode);
+
+// === CODE ===
+/**
+ * \fn Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Read from a file
+ */
+Uint64 Ext2_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       Uint64  base;
+       Uint    block;
+       Uint64  remLen;
+       
+       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
+       
+       // Get Inode
+       Ext2_int_GetInode(Node, &inode);
+       
+       // Sanity Checks
+       if(Offset >= inode.i_size) {
+               LEAVE('i', 0);
+               return 0;
+       }
+       if(Offset + Length > inode.i_size)
+               Length = inode.i_size - Offset;
+       
+       block = Offset / disk->BlockSize;
+       Offset = Offset / disk->BlockSize;
+       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+       if(base == 0) {
+               Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
+               LEAVE('i', 0);
+               return 0;
+       }
+       
+       // Read only block
+       if(Length <= disk->BlockSize - Offset)
+       {
+               VFS_ReadAt( disk->FD, base+Offset, Length, Buffer);
+               LEAVE('X', Length);
+               return Length;
+       }
+       
+       // Read first block
+       remLen = Length;
+       VFS_ReadAt( disk->FD, base + Offset, disk->BlockSize - Offset, Buffer);
+       remLen -= disk->BlockSize - Offset;
+       Buffer += disk->BlockSize - Offset;
+       block ++;
+       
+       // Read middle blocks
+       while(remLen > disk->BlockSize)
+       {
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               if(base == 0) {
+                       Warning("[EXT2 ] NULL Block Detected in INode 0x%llx", Node->Inode);
+                       LEAVE('i', 0);
+                       return 0;
+               }
+               VFS_ReadAt( disk->FD, base, disk->BlockSize, Buffer);
+               Buffer += disk->BlockSize;
+               remLen -= disk->BlockSize;
+               block ++;
+       }
+       
+       // Read last block
+       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+       VFS_ReadAt( disk->FD, base, remLen, Buffer);
+       
+       LEAVE('X', Length);
+       return Length;
+}
diff --git a/Modules/FS_Ext2/write.c b/Modules/FS_Ext2/write.c
new file mode 100644 (file)
index 0000000..f3fdc6b
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Acess OS
+ * Ext2 Driver Version 1
+ */
+/**
+ * \file write.c
+ * \brief Second Extended Filesystem Driver
+ * \todo Implement file full write support
+ */
+#define DEBUG  1
+#define VERBOSE        0
+#include "ext2_common.h"
+
+// === PROTOYPES ===
+Uint64         Ext2_Write(tVFS_Node *node, Uint64 offset, Uint64 length, void *buffer);
+Uint32         Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock);
+
+// === CODE ===
+/**
+ * \fn Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ * \brief Write to a file
+ */
+Uint64 Ext2_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tExt2_Disk      *disk = Node->ImplPtr;
+       tExt2_Inode     inode;
+       Uint64  base;
+       Uint64  retLen;
+       Uint    block;
+       Uint64  allocSize;
+        int    bNewBlocks = 0;
+       
+       Debug_HexDump("Ext2_Write", Buffer, Length);
+       
+       Ext2_int_GetInode(Node, &inode);
+       
+       // Get the ammount of space already allocated
+       // - Round size up to block size
+       // - block size is a power of two, so this will work
+       allocSize = (inode.i_size + disk->BlockSize) & ~(disk->BlockSize-1);
+       
+       // Are we writing to inside the allocated space?
+       if( Offset < allocSize )
+       {
+               // Will we go out of it?
+               if(Offset + Length > allocSize) {
+                       bNewBlocks = 1;
+                       retLen = allocSize - Offset;
+               } else
+                       retLen = Length;
+               
+               // Within the allocated space
+               block = Offset / disk->BlockSize;
+               Offset %= disk->BlockSize;
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               
+               // Write only block (if only one)
+               if(Offset + retLen <= disk->BlockSize) {
+                       VFS_WriteAt(disk->FD, base+Offset, retLen, Buffer);
+                       if(!bNewBlocks) return Length;
+                       goto addBlocks; // Ugh! A goto, but it seems unavoidable
+               }
+               
+               // Write First Block
+               VFS_WriteAt(disk->FD, base+Offset, disk->BlockSize-Offset, Buffer);
+               Buffer += disk->BlockSize-Offset;
+               retLen -= disk->BlockSize-Offset;
+               block ++;
+               
+               // Write middle blocks
+               while(retLen > disk->BlockSize)
+               {
+                       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+                       VFS_WriteAt(disk->FD, base, disk->BlockSize, Buffer);
+                       Buffer += disk->BlockSize;
+                       retLen -= disk->BlockSize;
+                       block ++;
+               }
+               
+               // Write last block
+               base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
+               VFS_WriteAt(disk->FD, base, retLen, Buffer);
+               if(!bNewBlocks) return Length;  // Writing in only allocated space
+       }
+       
+addBlocks:
+       ///\todo Implement block allocation
+       Warning("[EXT2] File extending is not yet supported");
+       
+       return 0;
+}
+
+/**
+ * \fn Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
+ * \brief Allocate a block from the best possible location
+ * \param Disk EXT2 Disk Information Structure
+ * \param PrevBlock    Previous block ID in the file
+ */
+Uint32 Ext2_int_AllocateBlock(tExt2_Disk *Disk, Uint32 PrevBlock)
+{
+        int    bpg = Disk->SuperBlock.s_blocks_per_group;
+       Uint    blockgroup = PrevBlock / bpg;
+       Uint    bitmap[Disk->BlockSize/sizeof(Uint)];
+       Uint    bitsperblock = 8*Disk->BlockSize;
+        int    i, j = 0;
+       Uint    block;
+       
+       // Are there any free blocks?
+       if(Disk->SuperBlock.s_free_blocks_count == 0)   return 0;
+       
+       if(Disk->Groups[blockgroup].bg_free_blocks_count > 0)
+       {
+               // Search block group's bitmap
+               for(i = 0; i < bpg; i++)
+               {
+                       // Get the block in the bitmap block
+                       j = i & (bitsperblock-1);
+                       
+                       // Read in if needed
+                       if(j == 0) {
+                               VFS_ReadAt(
+                                       Disk->FD,
+                                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
+                                       Disk->BlockSize,
+                                       bitmap
+                                       );
+                       }
+                       
+                       // Fast Check
+                       if( bitmap[j/32] == -1 ) {
+                               j = (j + 31) & ~31;
+                               continue;
+                       }
+                       
+                       // Is the bit set?
+                       if( bitmap[j/32] & (1 << (j%32)) )
+                               continue;
+                       
+                       // Ooh! We found one
+                       break;
+               }
+               if( i < bpg ) {
+                       Warning("[EXT2 ] Inconsistency detected, Group Free Block count is non-zero when no free blocks exist");
+                       goto    checkAll;       // Search the entire filesystem for a free block
+                       // Goto needed for neatness
+               }
+               
+               // Mark as used
+               bitmap[j/32] |= (1 << (j%32));
+               VFS_WriteAt(
+                       Disk->FD,
+                       (Uint64)Disk->Groups[blockgroup].bg_block_bitmap + i / bitsperblock,
+                       Disk->BlockSize,
+                       bitmap
+                       );
+               block = i;
+               Disk->Groups[blockgroup].bg_free_blocks_count --;
+               #if EXT2_UPDATE_WRITEBACK
+               //Ext2_int_UpdateBlockGroup(blockgroup);
+               #endif
+       }
+       else
+       {
+       checkAll:
+               Warning("[EXT2 ] TODO - Implement using blocks outside the current block group");
+               return 0;
+       }
+       
+       // Reduce global count
+       Disk->SuperBlock.s_free_blocks_count --;
+       #if EXT2_UPDATE_WRITEBACK
+       Ext2_int_UpdateSuperblock(Disk);
+       #endif
+       
+       return block;
+}
index 65037ef..2f1950a 100644 (file)
@@ -60,8 +60,8 @@ int UHCI_Initialise()
        if(i == MAX_CONTROLLERS) {\r
                Warning("[UHCI ] Over "EXPAND_STR(MAX_CONTROLLERS)" UHCI controllers detected, ignoring rest");\r
        }\r
-       LEAVE('i', 0);\r
-       return 0;\r
+       LEAVE('i', i);\r
+       return i;\r
 }\r
 \r
 /**\r
@@ -71,13 +71,13 @@ int UHCI_Initialise()
 void UHCI_Cleanup()\r
 {\r
 }
-
-/**
- * \fn int UHCI_IOCtl(tVFS_Node *Node, int ID, void *Data)
- */
-int UHCI_IOCtl(tVFS_Node *Node, int ID, void *Data)
-{
-       return 0;
+\r
+/**\r
+ * \brief Sends a packet to a device endpoint\r
+ */\r
+int UHCI_SendPacket(int ControllerId, int Device, int Endpoint, void *Data, int Length)\r
+{\r
+       return 0;\r
 }\r
 \r
 // === INTERNAL FUNCTIONS ===\r
index 3e503ec..1ccf98c 100644 (file)
@@ -9,6 +9,68 @@
 typedef struct sUSBHost        tUSBHost;
 typedef struct sUSBDevice      tUSBDevice;
 
+// === CONSTANTS ===
+enum eUSB_PIDs
+{
+       /**
+        * \name Token
+        * \{
+        */
+       PID_OUT         = 0xE1,
+       PID_IN          = 0x69,
+       PID_SOF         = 0xA5,
+       PID_SETUP       = 0x2D,
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Data
+        * \{
+        */
+       PID_DATA0       = 0xC3,
+       PID_DATA1       = 0x4B,
+       PID_DATA2       = 0x87, // USB2 only
+       PID_MDATA       = 0x0F, // USB2 only
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Handshake
+        * \{
+        */
+       PID_ACK         = 0xD2,
+       PID_NAK         = 0x5A,
+       PID_STALL       = 0x1E,
+       PID_NYET        = 0x96,
+       /**
+        * \}
+        */
+       
+       /**
+        * \name Special
+        * \{
+        */
+       PID_PRE         = 0x3C, PID_ERR         = 0x3C,
+       PID_SPLIT       = 0x78,
+       PID_PING        = 0xB4,
+       PID_RESVD       = 0xF0,
+       /**
+        * \}
+        */
+};
+
+// === FUNCTIONS ===
+/**
+ * \note 00101 - X^5+X^2+1
+ */
+Uint8  USB_TokenCRC(void *Data, int len);
+/**
+ * \note X^16 + X15 + X^2 + 1
+ */
+Uint16 USB_TokenCRC(void *Data, int len);
+
 // === STRUCTURES ===
 /**
  * \brief Defines a USB Host Controller
diff --git a/README b/README
index 61e69d2..6890ba3 100644 (file)
--- a/README
+++ b/README
@@ -40,5 +40,10 @@ DRIVERS defines what device drivers are to be included from the Kernel
 MODULES defines what modules should be statically linked with the kernel
   (see /Modules for a list)
 
-Finally set the source root directory (ACESSDIR) and the destination
-  directory (DISTROOT) then call make in the source root.
+Set the source root directory (ACESSDIR) and the destination  directory
+ (DISTROOT).
+
+Now you can compile the kernel and usermode applications by calling make
+ in the source root.
+
+
index 49c5eb4..9f773dc 100644 (file)
@@ -1,11 +1,13 @@
 /*\r
-AcessOS Basic Lib C\r
-\r
-lib.h\r
+ * Acess2 Basic Lib C\r
+ * lib.h\r
 */\r
 #ifndef _LIB_H\r
 #define _LIB_H\r
 \r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
 #define BUILD_SO       1\r
 \r
 #if defined(BUILD_DLL)\r
@@ -18,4 +20,12 @@ lib.h
 \r
 extern void *memcpy(void *dest, const void *src, size_t n);\r
 \r
+typedef struct sCPUID  tCPUID;\r
+\r
+struct sCPUID\r
+{\r
+       uint8_t SSE;\r
+       uint8_t SSE2;\r
+};\r
+\r
 #endif\r
index a10d9d1..0233b97 100644 (file)
@@ -2,13 +2,21 @@
  * AcessOS Basic C Library\r
  */\r
 #include "stdio_int.h"\r
+#include "lib.h"\r
 \r
+// === PROTOTYPES ===\r
+static void    cpuid(uint32_t Num, uint32_t *EAX, uint32_t *EBX, uint32_t *EDX, uint32_t *ECX);\r
+\r
+// === GLOBALS ===\r
 extern char **_envp;\r
 extern struct sFILE    _iob[];\r
 extern struct sFILE    *stdin;\r
 extern struct sFILE    *stdout;\r
 extern struct sFILE    *stderr;\r
+// --- CPU Features ---\r
+tCPUID gCPU_Features;\r
 \r
+// === CODE ===\r
 /**\r
  * \fn int SoMain()\r
  * \brief Stub Entrypoint\r
@@ -30,5 +38,34 @@ int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)
        stderr = &_iob[2];\r
        stderr->FD = 2; stderr->Flags = FILE_FLAG_MODE_WRITE;\r
        \r
+       /*\r
+       {\r
+               uint32_t        ecx, edx;\r
+               cpuid(1, NULL, NULL, &edx, &ecx);\r
+               gCPU_Features.SSE  = edx & (1 << 25);   // SSE\r
+               gCPU_Features.SSE2 = edx & (1 << 26);   // SSE2\r
+       }\r
+       */\r
+       \r
        return 1;\r
 }\r
+\r
+\r
+/**\r
+ * \brief Call the CPUID opcode\r
+ */\r
+static void cpuid(uint32_t Num, uint32_t *EAX, uint32_t *EBX, uint32_t *EDX, uint32_t *ECX)\r
+{\r
+       uint32_t        eax, ebx, edx, ecx;\r
+       \r
+       __asm__ __volatile__ (\r
+               "cpuid"\r
+               : "=a"(eax), "=c"(ecx), "=d"(edx)\r
+               : "a"(Num)\r
+               );\r
+       \r
+       if(EAX) *EAX = eax;\r
+       if(EBX) *EBX = ebx;\r
+       if(EDX) *EDX = edx;\r
+       if(ECX) *ECX = ecx;\r
+}\r
index 1039430..bfbb625 100644 (file)
@@ -44,4 +44,7 @@ enum eDrv_Mouse {
        MSE_IOCTL_MAX_Y\r
 };
 
+// === Terminal ===
+#include "devices/terminal.h"
+
 #endif
diff --git a/Usermode/include/acess/devices/terminal.h b/Usermode/include/acess/devices/terminal.h
new file mode 100644 (file)
index 0000000..473271c
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * \file devices/terminal.h
+ */
+#ifndef _SYS_DEVICES_TERMINAL_H
+#define _SYS_DEVICES_TERMINAL_H
+
+
+enum eDrv_Terminal {
+       TERM_IOCTL_MODETYPE = 4,
+       TERM_IOCTL_WIDTH,
+       TERM_IOCTL_HEIGHT,
+       TERM_IOCTL_QUERYMODE
+};
+
+
+struct sTerm_IOCtl_Mode
+{
+       short   ID;             //!< Zero Based index of mode
+       short   DriverID;       //!< Driver's ID number (from ::tVideo_IOCtl_Mode)
+       Uint16  Height; //!< Height
+       Uint16  Width;  //!< Width
+       Uint8   Depth;  //!< Bits per cell
+       struct {
+               unsigned bText: 1;      //!< Text Mode marker
+               unsigned unused:        7;
+       };
+};
+
+/**
+ * \brief Terminal Modes
+ */
+enum eTplTerminal_Modes {
+       /**
+        * \brief UTF-8 Text Mode
+        * Any writes to the terminal file are treated as UTF-8 encoded
+        * strings and reads will also return UTF-8 strings.
+        */
+       TERM_MODE_TEXT,
+       
+       /**
+        * \brief 32bpp Framebuffer
+        * Writes to the terminal file will write to the framebuffer.
+        * Reads will return UTF-32 characters
+        */
+       TERM_MODE_FB,
+       
+       /**
+        * \brief OpenGL 2D/3D
+        * Writes to the terminal file will send 3D commands
+        * Reads will return UTF-32 characters
+        * \note May or may not stay in the spec
+        */
+       TERM_MODE_OPENGL,
+       
+       NUM_TERM_MODES
+};
+
+#endif

UCC git Repository :: git.ucc.asn.au