Cleanup
authorJohn Hodge <[email protected]>
Fri, 2 Oct 2009 13:00:47 +0000 (21:00 +0800)
committerJohn Hodge <[email protected]>
Fri, 2 Oct 2009 13:00:47 +0000 (21:00 +0800)
- Unified the build systems for user and kernel space code
- Fixed bug in VFS when VFS_Open is called by user when the current working directory is NULL
- Added testing EXT2 and NE2000 drivers
- Added files forgotten in the FDD commit

43 files changed:
Kernel/Makefile
Kernel/Makefile.cfg [deleted file]
Kernel/arch/x86/Makefile
Kernel/arch/x86/errors.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.c
Kernel/binary.c
Kernel/debug.c
Kernel/drv/ne2000.c [new file with mode: 0644]
Kernel/include/common.h
Kernel/include/dma.h [new file with mode: 0644]
Kernel/include/signal.h [new file with mode: 0644]
Kernel/include/threads.h
Kernel/syscalls.c
Kernel/system.c
Kernel/threads.c
Kernel/vfs/fs/ext2.c [new file with mode: 0644]
Kernel/vfs/fs/fs_ext2.h [new file with mode: 0644]
Kernel/vfs/open.c
Makefile.cfg [new file with mode: 0644]
README [new file with mode: 0644]
Usermode/Applications/CLIShell_src/Makefile
Usermode/Applications/Makefile.cfg [new file with mode: 0644]
Usermode/Applications/cat_src/Makefile
Usermode/Applications/init_src/Makefile
Usermode/Applications/login_src/Makefile
Usermode/Applications/login_src/header.h [new file with mode: 0644]
Usermode/Applications/ls_src/Makefile [new file with mode: 0644]
Usermode/Applications/ls_src/main.c [new file with mode: 0644]
Usermode/Libraries/Makefile.cfg [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/Makefile
Usermode/Libraries/ld-acess.so_src/helpers.asm [new file with mode: 0644]
Usermode/Libraries/ld-acess.so_src/link.ld [new file with mode: 0644]
Usermode/Libraries/libacess.so_src/Makefile
Usermode/Libraries/libc.so_src/Makefile
Usermode/Libraries/libc.so_src/config.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/crt0.asm [new file with mode: 0644]
Usermode/Libraries/libc.so_src/lib.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/stdio_int.h [new file with mode: 0644]
Usermode/Libraries/libc.so_src/string.c [new file with mode: 0644]
Usermode/Libraries/libgcc.so_src/Makefile [new file with mode: 0644]
Usermode/Libraries/libgcc.so_src/libgcc.c [new file with mode: 0644]
Usermode/include/string.h [new file with mode: 0644]

index e153483..ae42dce 100644 (file)
@@ -4,12 +4,10 @@
 # - The built objects and dependency files are suffixed with the arch name
 # - The final binary is Acess2.<ARCH>.bin
 
--include Makefile.cfg
+-include ../Makefile.cfg
 
 -include arch/$(ARCHDIR)/Makefile
 
-RM = rm -f
-
 MAKEDEP                = $(CC) -M
 
 CPPFLAGS       += -I./include -I./arch/$(ARCHDIR)/include -DARCH=$(ARCH)
@@ -43,9 +41,9 @@ $(BIN): $(OBJ) arch/$(ARCHDIR)/link.ld Makefile
        @echo --- LD -o $(BIN)
        @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) -Map ../Map.$(ARCH).txt
        @objdump $(BIN) -D > $(BIN).dsm
-       @cp $(BIN) /mnt/AcessFDD/
+       cp $(BIN) $(DISTROOT)
        @wc -l $(SRCFILES) > LineCounts.$(ARCH).txt
-       @git commit -a
+#      @git commit -a
 
 %.ao.$(ARCH): %.asm Makefile
        @echo --- NASM -o $@
diff --git a/Kernel/Makefile.cfg b/Kernel/Makefile.cfg
deleted file mode 100644 (file)
index 8e186b8..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# 
-# Acess2 Makefile Config
-# Makefile.cfg
-
-ARCH = i386
-ARCHDIR = x86
index 335d219..051d126 100644 (file)
@@ -4,10 +4,10 @@
 # arch/i386/Makefile
 
 # Assuming build machine is 32-bit ELF
-CC = gcc
-AS = nasm
-LD = ld
-OBJDUMP = objdump
+#CC = gcc
+#AS = nasm
+#LD = ld
+#OBJDUMP = objdump
 
 CPPFLAGS       =
 CFLAGS         =
index 2c3582c..0c2da16 100644 (file)
@@ -5,10 +5,16 @@
  */
 #include <common.h>
 
+// === CONSTANTS ===
+#define        MAX_BACKTRACE   8       //!< Maximum distance to trace the stack backwards
+
 // === IMPORTS ===
 extern void    MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs);
 extern void Threads_Dump();
 
+// === PROTOTYPES ===
+void   Error_Backtrace(Uint eip, Uint ebp);
+
 // === CODE ===
 /**
  * \fn void ErrorHandler(tRegs *Regs)
@@ -45,8 +51,63 @@ void ErrorHandler(tRegs *Regs)
        __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr));
        Warning(" CR3: 0x%08x", cr);
        
+       // Print Stack Backtrace
+       Error_Backtrace(Regs->eip, Regs->ebp);
+       
        // Dump running threads
        Threads_Dump();
        
        for(;;) __asm__ __volatile__ ("hlt");
 }
+/**
+ * \fn void Error_Backtrace(Uint eip, Uint ebp)
+ * \brief Unrolls the stack to trace execution
+ */
+void Error_Backtrace(Uint eip, Uint ebp)
+{
+        int    i = 0;
+       Uint    delta = 0;
+       char    *str = NULL;
+       
+       //if(eip < 0xC0000000 && eip > 0x1000)
+       //{
+       //      LogF("Backtrace: User - 0x%x\n", eip);
+       //      return;
+       //}
+       
+       if(eip > 0xE0000000)
+       {
+               LogF("Backtrace: Data Area - 0x%x\n", eip);
+               return;
+       }
+       
+       if(eip > 0xC8000000)
+       {
+               LogF("Backtrace: Kernel Module - 0x%x\n", eip);
+               return;
+       }
+       
+       //str = Debug_GetSymbol(eip, &delta);
+       if(str == NULL)
+               LogF("Backtrace: 0x%x", eip);
+       else
+               LogF("Backtrace: %s+0x%x", str, delta);
+       if(!MM_GetPhysAddr(ebp))
+       {
+               LogF("\nBacktrace: Invalid EBP, stopping\n");
+               return;
+       }
+       
+       
+       while( MM_GetPhysAddr(ebp) && i < MAX_BACKTRACE )
+       {
+               //str = Debug_GetSymbol(*(Uint*)(ebp+4), &delta);
+               if(str == NULL)
+                       LogF(" >> 0x%x", *(Uint*)(ebp+4));
+               else
+                       LogF(" >> %s+0x%x", str, delta);
+               ebp = *(Uint*)ebp;
+               i++;
+       }
+       LogF("\n");
+}
index 2b7d191..3663d60 100644 (file)
@@ -41,6 +41,7 @@
 extern Uint32  gaInitPageDir[1024];
 extern Uint32  gaInitPageTable[1024];
 extern void    Threads_SegFault(Uint Addr);
+extern void    Error_Backtrace(Uint eip, Uint ebp);
 
 // === PROTOTYPES ===
 void   MM_PreinitVirtual();
@@ -145,12 +146,14 @@ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs)
                        );
        }
        
+       Log("Code at %p accessed %p", Regs->eip, Addr);
+       // Print Stack Backtrace
+       Error_Backtrace(Regs->eip, Regs->ebp);
+       
        Log("gaPageDir[0x%x] = 0x%x", Addr>>22, gaPageDir[Addr>>22]);
        if( gaPageDir[Addr>>22] & PF_PRESENT )
                Log("gaPageTable[0x%x] = 0x%x", Addr>>12, gaPageTable[Addr>>12]);
        
-       Log("Code at %p accessed %p\n", Regs->eip, Addr);
-       
        MM_DumpTables(0, -1);   
        
        Panic("Page Fault at 0x%x\n", Regs->eip);
index 5cfc7a2..f7bda0f 100644 (file)
@@ -33,6 +33,7 @@ extern tThread        *gSleepingThreads;
 extern tThread *gDeleteThreads;
 extern tThread *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump();
+extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
 
 // === PROTOTYPES ===
 void   ArchThreads_Init();
@@ -242,24 +243,19 @@ int Proc_Clone(Uint *Err, Uint Flags)
        __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
        __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
        
-       // Create new thread structure
-       newThread = malloc( sizeof(tThread) );
-       if(!newThread) {
-               Warning("Proc_Clone - Out of memory when creating thread\n");
-               *Err = -ENOMEM;
-               return -1;
-       }
-       
-       // Base new thread on current
-       memcpy(newThread, cur, sizeof(tThread));
+       newThread = Threads_CloneTCB(Err, Flags);
+       if(!newThread)  return -1;
        
        // Initialise Memory Space (New Addr space or kernel stack)
        if(Flags & CLONE_VM) {
-               newThread->TGID = newThread->TID;
                newThread->MemState.CR3 = MM_Clone();
+               newThread->KernelStack = cur->KernelStack;
        } else {
                Uint    tmpEbp, oldEsp = esp;
 
+               // Set CR3
+               newThread->MemState.CR3 = cur->MemState.CR3;
+
                // Create new KStack
                newThread->KernelStack = MM_NewKStack();
                // Check for errors
@@ -285,23 +281,6 @@ int Proc_Clone(Uint *Err, Uint Flags)
                                *(Uint*)tmpEbp += newThread->KernelStack - cur->KernelStack;
                }
        }
-
-       // Set Pointer, Spinlock and TID
-       newThread->Next = NULL;
-       newThread->IsLocked = 0;
-       newThread->TID = giNextTID++;
-       newThread->PTID = cur->TID;
-       
-       // Create copy of name
-       newThread->ThreadName = malloc(strlen(cur->ThreadName)+1);
-       strcpy(newThread->ThreadName, cur->ThreadName);
-
-       // Clear message list (messages are not inherited)
-       newThread->Messages = NULL;
-       newThread->LastMessage = NULL;
-       
-       // Set remaining (sheduler expects remaining to be correct)
-       newThread->Remaining = newThread->Quantum;
        
        // Save core machine state
        newThread->SavedState.ESP = esp;
@@ -318,8 +297,6 @@ int Proc_Clone(Uint *Err, Uint Flags)
        // Lock list and add to active
        Threads_AddActive(newThread);
        
-       //Threads_Dump();
-       
        return newThread->TID;
 }
 
index 1884af8..dae3cfa 100644 (file)
@@ -25,8 +25,8 @@ typedef struct sKernelBin {
 extern int     Proc_Clone(Uint *Err, Uint Flags);\r
 extern void    Threads_SetName(char *Name);\r
 extern char    *Threads_GetName(int ID);\r
+extern void    Threads_Exit(int, int);\r
 extern Uint    MM_ClearUser();\r
-extern void    Threads_Exit();\r
 extern void    Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize);\r
 extern tKernelSymbol   gKernelSymbols[];\r
 extern void            gKernelSymbolsEnd;\r
@@ -147,7 +147,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
        if(bases[0] == 0)\r
        {\r
                Warning("Proc_Execve - Unable to load '%s'", Threads_GetName(-1));\r
-               Threads_Exit();\r
+               Threads_Exit(0, 0);\r
                for(;;);\r
        }\r
        \r
index bd3b407..bf2282f 100644 (file)
@@ -314,7 +314,6 @@ void Debug_HexDump(char *Header, void *Data, Uint Length)
                cdat --;
        }
        E9('\n');
-       
 }
 
 // --- EXPORTS ---
diff --git a/Kernel/drv/ne2000.c b/Kernel/drv/ne2000.c
new file mode 100644 (file)
index 0000000..e1f5990
--- /dev/null
@@ -0,0 +1,213 @@
+/* Acess2
+ * NE2000 Driver
+ * 
+ * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
+ */
+#include <common.h>
+#include <modules.h>
+#include <fs_devfs.h>
+
+// === CONSTANTS ===
+static const struct {
+       Uint16  Vendor;
+       Uint16  Device;
+} csaCOMPAT_DEVICES[] = {
+       {0x10EC, 0x8029},       // Realtek 8029
+       {0x10EC, 0x8129}        // Realtek 8129
+};
+#define NUM_COMPAT_DEVICES     (sizeof(csaCOMPAT_DEVICES)/sizeof(csaCOMPAT_DEVICES[0]))
+
+enum eNe2k_Page0Read {
+       COMMAND = 0,    //!< the master command register
+       CLDA0,          //!< Current Local DMA Address 0
+       CLDA1,          //!< Current Local DMA Address 1
+       BNRY,           //!< Boundary Pointer (for ringbuffer)
+       TSR,            //!< Transmit Status Register
+       NCR,            //!< collisions counter
+       FIFO,           //!< (for what purpose ??)
+       ISR,            //!< Interrupt Status Register
+       CRDA0,          //!< Current Remote DMA Address 0
+       CRDA1,          //!< Current Remote DMA Address 1
+       RSR = 0xC       //!< Receive Status Register
+};
+
+enum eNe2k_Page0Write {
+       PTART = 1,      //!< page start (init only)
+       PSTOP,          //!< page stop  (init only)
+       TPSR = 4,       //!< transmit page start address
+       TBCR0,          //!< transmit byte count (low)
+       TBCR1,          //!< transmit byte count (high)
+       RSAR0 = 8,      //!< remote start address (lo)
+       RSAR1,  //!< remote start address (hi)
+       RBCR0,  //!< remote byte count (lo)
+       RBCR1,  //!< remote byte count (hi)
+       RCR,    //!< receive config register
+       TCR,    //!< transmit config register
+       DCR,    //!< data config register    (init)
+       IMR             //!< interrupt mask register (init)
+};
+
+// === TYPES ===
+typedef struct sNe2k_Card {
+       Uint16  IOBase; //!< IO Port Address from PCI
+       Uint8   IRQ;    //!< IRQ Assigned from PCI
+       
+        int    NextMemPage;    //!< Next Card Memory page to use
+       
+       char    Name[2];        // "0"
+       tVFS_Node       *Node;
+       char    MacAddr[6];
+} tCard;
+
+// === PROTOTYPES ===
+ int   Ne2k_Install(char **Arguments);
+Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, 0x0032, Ne2k, Ne2k_Install, NULL, NULL);
+tDevFS_Driver  gNe2k_DriverInfo = {
+       NULL, "ne2k",
+       {
+       .NumACLs = 1,
+       .ACLs = &gVFS_ACL_EveryoneRW,
+       .Flags = VFS_FFLAG_DIRECTORY
+       }
+};
+Uint16 gNe2k_BaseAddress;
+ int   giNe2k_CardCount = 0;
+
+// === CODE ===
+/**
+ * \fn int Ne2k_Install(char **Options)
+ * \brief Installs the NE2000 Driver
+ */
+int Ne2k_Install(char **Options)
+{
+        int    i, j, k;
+       
+       // --- Scan PCI Bus ---
+       // Count Cards
+       giNe2k_CardCount = 0;
+       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
+       {
+               giNe2k_CardCount += PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
+       }
+       
+       // Enumerate Cards
+       k = 0;
+       gpNe2k_Cards = malloc( giNe2k_CardCount * sizeof(tCard) );
+       memsetd(gpNe2k_Cards, 0, giNe2k_CardCount * sizeof(tCard) / 4);
+       for( i = 0; i < NUM_COMPAT_DEVICES; i ++ )
+       {
+               count = PCI_CountDevices( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0 );
+               for( j = 0; j < count; j ++,k ++ )
+               {
+                       id = PCI_GetDevice( csaCOMPAT_DEVICES[i].Vendor, csaCOMPAT_DEVICES[i].Device, 0, j );
+                       // Create Structure
+                       base = PCI_AssignPort( id, 0, 0x20 );
+                       gpNe2k_Cards[ k ].IOBase = base;
+                       gpNe2k_Cards[ k ].IRQ = PCI_GetIRQ( id );
+                       gpNe2k_Cards[ k ].NextMemPage = 1;
+                       
+                       //Install IRQ6 Handler
+                       IRQ_Set(gpNe2k_Cards[ k ].IRQ, Ne2k_IRQHandler);
+                       
+                       // Reset Card
+                       outb( base + 0x1F, inb(base + 0x1F) );
+                       while( (inb( base+ISR ) & 0x80) == 0 );
+                       outb( base + ISR, 0x80 );
+                       
+                       // Initialise Card
+                       outb( base + COMMAND, 0x21 );   // No DMA and Stop
+                       outb( base + DCR, 0x49 );       // Set WORD mode
+                       outb( base + IMR, 0x00 );
+                       outb( base + ISR, 0xFF );
+                       outb( base + RCR, 0x20 );       // Reciever to Monitor
+                       outb( base + TCR, 0x02 );       // Transmitter OFF
+                       outb( base + RBCR0, 6*4 );      // Remote Byte Count
+                       outb( base + RBCR1, 0 );
+                       outb( base + RSAR0, 0 );        // Clear Source Address
+                       outb( base + RSAR1, 0 );
+                       outb( base + COMMAND, 0x0A );   // Remote Read, Start
+                       
+                       // Read MAC Address
+                       gpNe2k_Cards[ k ].MacAddr[0] = inb(base+0x10);  inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[1] = inb(base+0x10);  inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[2] = inb(base+0x10);  inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[3] = inb(base+0x10);  inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[4] = inb(base+0x10);  inb(base+0x10);
+                       gpNe2k_Cards[ k ].MacAddr[5] = inb(base+0x10);  inb(base+0x10);
+                       
+                       outb( base+PSTART, 0x60);       // Set Receive Start
+                       outb( base+BNRY, 0x7F); // Set Boundary Page
+                       outb( base+PSTOP, 0x80);        // Set Stop Page
+                       outb( base+ISR, 0xFF ); // Clear all ints
+                       outb( base+CMD, 0x22 ); // No DMA, Start
+                       outb( base+IMR, 0x3F ); // Set Interupt Mask
+                       outb( base+RCR, 0x8F ); // Set WRAP and allow all packet matches
+                       outb( base+TCR, 0x00 ); // Set Normal Transmitter mode
+                       outb( base+TPSR, 0x40); // Set Transmit Start
+                       
+                       // Set MAC Address
+                       /*
+                       Ne2k_WriteReg(base, MAC0, gpNe2k_Cards[ k ].MacAddr[0]);
+                       Ne2k_WriteReg(base, MAC1, gpNe2k_Cards[ k ].MacAddr[1]);
+                       Ne2k_WriteReg(base, MAC2, gpNe2k_Cards[ k ].MacAddr[2]);
+                       Ne2k_WriteReg(base, MAC3, gpNe2k_Cards[ k ].MacAddr[3]);
+                       Ne2k_WriteReg(base, MAC4, gpNe2k_Cards[ k ].MacAddr[4]);
+                       Ne2k_WriteReg(base, MAC5, gpNe2k_Cards[ k ].MacAddr[5]);
+                       */
+                       
+                       Log("[NE2K]: Card #%i: IRQ=%i, Base=0x%x, ",
+                               k, gpNe2k_Cards[ k ].IRQ, gpNe2k_Cards[ k ].PortBase,
+                               gpNe2k_Cards[ k ].Buffer);
+                       Log("MAC Address %x:%x:%x:%x:%x:%x\n",
+                               gpNe2k_Cards[ k ].MacAddr[0], gpNe2k_Cards[ k ].MacAddr[1],
+                               gpNe2k_Cards[ k ].MacAddr[2], gpNe2k_Cards[ k ].MacAddr[3],
+                               gpNe2k_Cards[ k ].MacAddr[4], gpNe2k_Cards[ k ].MacAddr[5]
+                               );
+                       
+                       // Set VFS Node
+                       gpNe2k_Cards[ k ].Name[0] = '0'+k;
+                       gpNe2k_Cards[ k ].Name[1] = '\0';
+                       gpNe2k_Cards[ k ].Node.NumACLs = 1;
+                       gpNe2k_Cards[ k ].Node.ACLs = gVFS_ACL_EveryoneRW;
+                       gpNe2k_Cards[ k ].Node.CTime = now();
+                       gpNe2k_Cards[ k ].Node.Write = Ne2k_Write;
+               }
+       }
+       
+       DevFS_AddDevice( &gNe2k_DriverInfo );
+       return 0;
+}
+
+
+/**
+ * \fn Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+ */
+Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+       tCard   *Card = (tCard*)Node->ImplPtr;
+       
+       // Sanity Check Length
+       if(Length > 0xFFFF)     return 0;
+       
+       outb(Card->IOBase + COMMAND, 0|0x22);   // Page 0, Start, NoDMA
+       // Send Size
+       outb(Card->IOBase + RBCR0, Count & 0xFF);
+       outb(Card->IOBase + RBCR1, Count >> 8);
+       // Clear Remote DMA Flag
+       outb(Card->IOBase + ISR, 0x40); // Bit 6
+       // Set up transfer
+       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
+       outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length));        // Page Offset
+       return 0;
+}
+
+/**
+ * \fn Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
+ */
+Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
+{
+       
+}
index 7bf5938..590295f 100644 (file)
 #include <arch.h>
 #include <stdarg.h>
 
+enum eConfigTypes {
+       CFGT_NULL,
+       CFGT_INT,
+       CFGT_HEAPSTR,
+       CFGT_PTR
+};
 enum eConfigs {
        CFG_VFS_CWD,
        CFG_VFS_MAXFILES,
        NUM_CFG_ENTRIES
 };
-#define CFGINT(_idx)   (*(Uint*)(MM_PPD_CFG+(_idx)*sizeof(void*)))
-#define CFGPTR(_idx)   (*(void**)(MM_PPD_CFG+(_idx)*sizeof(void*)))
+#define CFGINT(id)     (*Threads_GetCfgPtr(id))
+#define CFGPTR(id)     (*(void**)Threads_GetCfgPtr(id))
 
 // === CONSTANTS ===
 // --- Memory Flags --
@@ -43,6 +49,7 @@ extern void   Panic(char *Msg, ...);
 extern void    Warning(char *Msg, ...);
 extern void    Log(char *Fmt, ...);
 extern void    LogV(char *Fmt, va_list Args);
+extern void    LogF(char *Fmt, ...);
 extern void    Debug_Enter(char *FuncName, char *ArgTypes, ...);
 extern void    Debug_Log(char *FuncName, char *Fmt, ...);
 extern void    Debug_Leave(char *FuncName, char RetType, ...);
@@ -114,10 +121,10 @@ extern  int       Proc_Spawn(char *Path);
 extern void    Threads_Exit();
 extern void    Threads_Yield();
 extern void    Threads_Sleep();
-extern int     Threads_GetCfg(int Index);
 extern int     Threads_GetUID();
 extern int     Threads_GetGID();
 extern int     SpawnTask(tThreadFunction Function, void *Arg);
+extern Uint    *Threads_GetCfgPtr(int Id);
 
 #include <binary_ext.h>
 #include <vfs_ext.h>
diff --git a/Kernel/include/dma.h b/Kernel/include/dma.h
new file mode 100644 (file)
index 0000000..5b0bbda
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Acess2 DMA Driver
+ */
+#ifndef _DMA_H_
+#define _DMA_H_
+
+extern void    DMA_SetChannel(int channel, int length, int read);
+extern int     DMA_ReadData(int channel, int count, void *buffer);
+
+#endif
diff --git a/Kernel/include/signal.h b/Kernel/include/signal.h
new file mode 100644 (file)
index 0000000..d97d6dc
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 Kernel
+ * Signal List
+ */
+#ifndef _SIGNAL_H_
+#define _SIGNAL_H_
+
+enum eSignals {
+       SIGKILL,
+       SIGSTOP,
+       SIGCONT,
+       SIGCHLD,
+       NSIG
+};
+
+#endif
index 377b6ac..1e15547 100644 (file)
@@ -16,6 +16,7 @@ typedef struct sMessage
 
 typedef struct sThread
 {
+       // --- threads.c's
        struct sThread  *Next;  //!< Next thread in list
         int    IsLocked;       //!< Thread's spinlock
         int    Status;         //!< Thread Status
@@ -27,7 +28,9 @@ typedef struct sThread
        Uint    UID, GID;       //!< User and Group
        char    *ThreadName;    //!< Name of thread
        
-       tVAddr  KernelStack;    //!< Kernel Stack Base
+       // --- arch/proc.c's responsibility
+       //! Kernel Stack Base
+       tVAddr  KernelStack;
        
        //! Memory Manager State
        tMemoryState    MemState;
@@ -35,6 +38,7 @@ typedef struct sThread
        //! State on task switch
        tTaskState      SavedState;
        
+       // --- threads.c's
         int    CurSignal;      //!< Signal currently being handled (0 for none)
        tVAddr  SignalHandlers[NSIG];   //!< Signal Handler List
        tTaskState      SignalState;    //!< Saved state for signal handler
index dd1f4b3..5774dbe 100644 (file)
@@ -119,6 +119,11 @@ void SyscallHandler(tSyscallRegs *Regs)
        // Binary Control
        // ---
        case SYS_EXECVE:
+               if( !Syscall_ValidString(Regs->Arg1) ) {
+                       err = -EINVAL;
+                       ret = -1;
+                       break;
+               }
                ret = Proc_Execve((char*)Regs->Arg1, (char**)Regs->Arg2, (char**)Regs->Arg3);
                break;
        case SYS_LOADBIN:
index 26ce100..9b160d9 100644 (file)
@@ -19,7 +19,6 @@ void  System_ExecuteScript();
  int   System_Int_GetString(char *Str, char **Dest);
 
 // === GLOBALS ===
-char   *gsInitPath = "/Acess/Bin/init";
 char   *gsConfigScript = "/Acess/Conf/BootConf.cfg";
 
 // === CODE ===
index 54438c3..5f2e3d7 100644 (file)
@@ -5,11 +5,17 @@
  */
 #include <common.h>
 #include <threads.h>
+#include <errno.h>
 
 // === CONSTANTS ===
 #define        DEFAULT_QUANTUM 10
 #define        DEFAULT_TICKETS 5
 #define MAX_TICKETS            10
+const enum eConfigTypes        cCONFIG_TYPES[] = {
+       CFGT_HEAPSTR,   // CFG_VFS_CWD
+       CFGT_INT,       // CFG_VFS_MAXFILES
+       CFGT_NULL
+};
 
 // === IMPORTS ===
 extern void    ArchThreads_Init();
@@ -22,6 +28,7 @@ void  Threads_Init();
 void   Threads_SetName(char *NewName);
 char   *Threads_GetName(int ID);
 void   Threads_SetTickets(int Num);
+tThread        *Threads_CloneTCB(Uint *Err, Uint Flags);
  int   Threads_WaitTID(int TID, int *status);
 tThread        *Threads_GetThread(Uint TID);
 void   Threads_AddToDelete(tThread *Thread);
@@ -148,6 +155,88 @@ void Threads_SetTickets(int Num)
        RELEASE( &giThreadListLock );
 }
 
+/**
+ * \fn tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
+ */
+tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
+{
+       tThread *cur, *new;
+        int    i;
+       cur = Proc_GetCurThread();
+       
+       new = malloc(sizeof(tThread));
+       if(new == NULL) {
+               *Err = -ENOMEM;
+               return NULL;
+       }
+       
+       new->Next = NULL;
+       new->IsLocked = 0;
+       new->Status = THREAD_STAT_ACTIVE;
+       new->RetStatus = 0;
+       
+       // Get Thread ID
+       new->TID = giNextTID++;
+       new->PTID = cur->TID;
+       
+       // Clone Name
+       new->ThreadName = malloc(strlen(cur->ThreadName)+1);
+       strcpy(new->ThreadName, cur->ThreadName);
+       
+       // Set Thread Group ID (PID)
+       if(Flags & CLONE_VM)
+               new->TGID = new->TID;
+       else
+               new->TGID = cur->TGID;
+       
+       // Messages are not inherited
+       new->Messages = NULL;
+       new->LastMessage = NULL;
+       
+       // Set State
+       new->Remaining = new->Quantum = cur->Quantum;
+       new->NumTickets = cur->NumTickets;
+       
+       // Set Signal Handlers
+       new->CurSignal = 0;
+       if(Flags & CLONE_VM)
+               memset(new->SignalHandlers, 0, sizeof(new->SignalHandlers));
+       else
+               memcpy(new->SignalHandlers, cur->SignalHandlers, sizeof(new->SignalHandlers));
+       memset(&new->SignalState, 0, sizeof(tTaskState));
+       
+       for( i = 0; i < NUM_CFG_ENTRIES; i ++ )
+       {
+               switch(cCONFIG_TYPES[i])
+               {
+               default:
+                       new->Config[i] = cur->Config[i];
+                       break;
+               case CFGT_HEAPSTR:
+                       if(cur->Config[i])
+                               new->Config[i] = (Uint) strdup( (void*)cur->Config[i] );
+                       else
+                               new->Config[i] = 0;
+                       break;
+               }
+       }
+       
+       return new;
+}
+
+/**
+ * \fn Uint *Threads_GetCfgPtr(int Id)
+ */
+Uint *Threads_GetCfgPtr(int Id)
+{
+       if(Id < 0 || Id >= NUM_CFG_ENTRIES) {
+               Warning("Threads_GetCfgPtr: Index %i is out of bounds", Id);
+               return NULL;
+       }
+       
+       return &Proc_GetCurThread()->Config[Id];
+}
+
 /**
  * \fn void Threads_WaitTID(int TID, int *status)
  * \brief Wait for a task to change state
@@ -408,7 +497,7 @@ void Threads_Sleep()
 }
 
 
-/**
+/**c0108919:
  * \fn void Threads_Wake( tThread *Thread )
  * \brief Wakes a sleeping/waiting thread up
  */
@@ -559,9 +648,10 @@ tThread *Threads_GetNextToRun(int CPU)
         int    ticket;
         int    number;
        
+       if(giNumActiveThreads == 0)     return NULL;
+       
        // Special case: 1 thread
-       if(giNumActiveThreads == 1)
-       {
+       if(giNumActiveThreads == 1) {
                return gActiveThreads;
        }
        
diff --git a/Kernel/vfs/fs/ext2.c b/Kernel/vfs/fs/ext2.c
new file mode 100644 (file)
index 0000000..78c115e
--- /dev/null
@@ -0,0 +1,584 @@
+/*\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 read support\r
+ */\r
+#include <common.h>\r
+#include <vfs.h>\r
+#include "fs_ext2.h"\r
+\r
+// === STRUCTURES ===\r
+typedef struct {\r
+        int    FD;\r
+        int    CacheID;\r
+       vfs_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
+//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
+char           *Ext2_ReadDir(tVFS_Node *Node, int Pos);\r
+tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, char *FileName);\r
+tVFS_Node      *Ext2_MkNod(tVFS_Node *Node, char *Name, Uint Flags);\r
+ int           Ext2_int_GetInode(vfs_node *Node, tExt2_Inode *Inode);\r
+tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId, char *Name, Uint64 VfsInode);\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
+\r
+// === SEMI-GLOBALS ===\r
+tExt2_Disk     gExt2_disks[6];\r
+ int   giExt2_count = 0;\r
+tVFS_Driver    gExt2_FSInfo = {NULL,\r
+       "ext2", 0, Ext2_InitDevice, Ext2_UnMount, NULL\r
+       };\r
+\r
+// === CODE ===\r
+\r
+/**\r
+ * \fn void Ext2_Install()\r
+ * \brief Install the Ext2 Filesystem Driver\r
+ */\r
+void Ext2_Install()\r
+{\r
+       VFS_AddDriver( &gExt2_FSInfo );\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
+       // 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'\n", Device);\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
+               WarningEx("EXT2", "Volume '%s' is not an EXT2 volume\n", Device);\r
+               VFS_Close(fd);\r
+               return NULL;\r
+       }\r
+       \r
+       // Get Group count\r
+       groupCount = DivUp(sb.s_blocks_count, sb.s_blocks_per_group);\r
+       //LogF(" Ext2_initDevice: groupCount = %i\n", groupCount);\r
+       \r
+       // Allocate Disk Information\r
+       disk = malloc(sizeof(tExt2_Disk) + sizeof(tExt2_Group)*groupCount);\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
+       //LogF(" Ext2_initDevice: s_log_block_size = 0x%x\n", sb.s_log_block_size);\r
+       disk->BlockSize = 1024 << sb.s_log_block_size;\r
+       \r
+       // Read Group Information\r
+       VFS_ReadAt(disk->fd,\r
+               sb.s_first_data_block * disk->BlockSize + 1024,\r
+               sizeof(tExt2_Group)*groupCount,\r
+               disk->Groups);\r
+       \r
+       #if 0\r
+       Log(" Ext2_initDevice: Block Group 0\n");\r
+       Log(" Ext2_initDevice: .bg_block_bitmap = 0x%x\n", disk->Groups[0].bg_block_bitmap);\r
+       Log(" Ext2_initDevice: .bg_inode_bitmap = 0x%x\n", disk->Groups[0].bg_inode_bitmap);\r
+       Log(" Ext2_initDevice: .bg_inode_table = 0x%x\n", disk->Groups[0].bg_inode_table);\r
+       Log(" Ext2_initDevice: Block Group 1\n");\r
+       Log(" Ext2_initDevice: .bg_block_bitmap = 0x%x\n", disk->Groups[1].bg_block_bitmap);\r
+       Log(" Ext2_initDevice: .bg_inode_bitmap = 0x%x\n", disk->Groups[1].bg_inode_bitmap);\r
+       Log(" Ext2_initDevice: .bg_inode_table = 0x%x\n", 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(vfs_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 0\r
+       Log(" Ext2_InitDevice: inode.i_size = 0x%x\n", inode.i_size);\r
+       Log(" Ext2_InitDevice: inode.i_block[0] = 0x%x\n", inode.i_block[0]);\r
+       #endif\r
+       \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
+       // Get Inode\r
+       Ext2_int_GetInode(Node, &inode);\r
+       \r
+       block = Offset / disk->BlockSize;\r
+       Offset = Offset / disk->BlockSize;\r
+       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);\r
+       \r
+       // Read only block\r
+       if(Length <= disk->BlockSize - Offset)\r
+       {\r
+               VFS_ReadAt( disk->fd, base+Offset, Length, Buffer);\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
+               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
+       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
+       Ext2_int_GetInode(Node, &inode);\r
+       \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
+       if( Offset < allocSize )\r
+       {\r
+               if(Offset + Length > allocSize) {\r
+                       bNewBlocks = 1;\r
+                       retLen = allocSize - Offset;\r
+               } else\r
+                       retLen = Length;\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
+       WarningEx("EXT2", "File extending is not yet supported");\r
+       \r
+       return 0;\r
+}\r
+\r
+/**\r
+ * \fn int Ext2_CloseFile(vfs_node *Node)\r
+ * \brief Close a file (Remove it from the cache)\r
+ */\r
+int Ext2_CloseFile(tVFS_Node *Node)\r
+{\r
+       tExt2_Disk      *disk = Node->ImplPtr;\r
+       inode_uncacheNode(disk->CacheID, Node->impl);\r
+       return 1;\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
+       Uint64  vfsInode = 0;\r
+       tVFS_Node       *retNode;\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\n", 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 ('%s') extends over a block boundary, ignoring\n",\r
+                                       entNum-1, Node->impl, Node->name);\r
+                       }\r
+                       ofs = 0;\r
+                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );\r
+               }\r
+       }\r
+       \r
+       if(size <= 0)   return NULL;\r
+       \r
+       // Read Entry\r
+       VFS_ReadAt( disk->fd, Base+ofs, sizeof(tExt2_DirEnt), &dirent );\r
+       //LOG(" Ext2_ReadDir: dirent.inode = %i\n", dirent.inode);\r
+       //LOG(" Ext2_ReadDir: dirent.rec_len = %i\n", dirent.rec_len);\r
+       //LOG(" Ext2_ReadDir: dirent.name_len = %i\n", 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
+                               Warnin("[EXT2 ] Directory Entry %i of inode %i ('%s') extends over a block boundary, ignoring\n",\r
+                                       entNum-1, Node->impl, Node->name);\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 tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, char *Name, int Flags)\r
+ * \brief Create a new node\r
+ */\r
+tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, char *Name, int Flags)\r
+{\r
+       return 0;\r
+}\r
+\r
+//==================================\r
+//=       INTERNAL FUNCTIONS       =\r
+//==================================\r
+\r
+\r
+/**\r
+ \internal\r
+ \fn int Ext2_int_GetInode(vfs_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
+               break;\r
+       // Directory\r
+       case EXT2_S_IFDIR:\r
+               retNode.ReadRir = 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)\n", 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
+       //LogF(" Ext2_int_ReadInode: group=%i, subId = %i\n", group, subId);\r
+       \r
+       //Seek to Block - Absolute\r
+       vfs_seek(Disk->fd, Disk->Groups[group].bg_inode_table * Disk->BlockSize, SEEK_SET);\r
+       //Seeek to inode - Relative\r
+       vfs_seek(Disk->fd, sizeof(tExt2_Inode)*subId, SEEK_CUR);\r
+       vfs_read(Disk->fd, sizeof(tExt2_Inode), 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
diff --git a/Kernel/vfs/fs/fs_ext2.h b/Kernel/vfs/fs/fs_ext2.h
new file mode 100644 (file)
index 0000000..9f84673
--- /dev/null
@@ -0,0 +1,154 @@
+/**\r
+ Acess Version 1\r
+ \file fs_ext2_int.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
+//STRUCTURES\r
+/**\r
+ \struct ext2_super_block_s\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\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
+ \struct ext2_dir_entry\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
+//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
index 0494294..6f03417 100644 (file)
@@ -61,7 +61,13 @@ char *VFS_GetAbsPath(char *Path)
                }
                strcpy(ret, Path);
        } else {
-               cwdLen = strlen(cwd);
+               if(cwd == NULL) {
+                       cwd = "/";
+                       cwdLen = 1;
+               }
+               else {
+                       cwdLen = strlen(cwd);
+               }
                endLen = cwdLen + pathLen + 2;
                // Prepend the current directory
                ret = malloc(endLen);
@@ -119,6 +125,7 @@ char *VFS_GetAbsPath(char *Path)
                write += (pos-read)+1;
        }
        
+       ret[write] = '\0';      // Cap string (to deal with . or .. being the last terms)
        // `ret` should now be the absolute path
        LEAVE('s', ret);
        //Log("VFS_GetAbsPath: RETURN '%s'", ret);
@@ -534,7 +541,8 @@ int VFS_ChDir(char *New)
        VFS_Close(fd);
        
        // Free old working directory
-       if( CFGPTR(CFG_VFS_CWD) )       free( CFGPTR(CFG_VFS_CWD) );
+       if( CFGPTR(CFG_VFS_CWD) )
+               free( CFGPTR(CFG_VFS_CWD) );
        // Set new
        CFGPTR(CFG_VFS_CWD) = buf;
        
diff --git a/Makefile.cfg b/Makefile.cfg
new file mode 100644 (file)
index 0000000..65d3fa0
--- /dev/null
@@ -0,0 +1,15 @@
+#
+# Acess2 Build Configuration
+#
+
+CC = gcc
+LD = ld
+AS = nasm
+OBJDUMP = objdump
+RM = @rm -f
+STRIP = strip
+
+ARCH = i386
+ARCHDIR = x86
+
+DISTROOT = /mnt/AcessHDD/Acess2
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..66d70f1
--- /dev/null
+++ b/README
@@ -0,0 +1,31 @@
+========
+ Acess2
+========
+
+Acess2 is [TPG]'s hobby operating system.
+
+The Acess kernel is SEMI-posix compilant, but will be a comatability
+library that emulates the different functions.
+
+=== Source Tree ===
+--- /Kernel ---
+The /Kernel tree contains the kernel sources.
+ Within the root of the tree is the miscelanious architecture agnostic
+   code for managing threads, loading modules and other things.
+ /Kernel/arch/<archname> - Architecture dependent code
+ /Kernel/bin - Binary file format parsers. Takes a binary file and
+   convertes it into a binary object that the loader can then load into memory.
+ /Kernel/vfs - The Virtual Filesystem
+ /Kernel/vfs/fs - The various filesystem drivers for the VFS.
+ /Kernel/drv - Drivers
+
+--- Usermode ---
+/Usermode contains the base acess system
+ /Usermode/Applications - Usermode applications such as the default
+   command shell and the login shell.
+ /Usermode/Libraries - Usermode shared libraries and crt0.o, currently
+   implemented are libacess (kernel interface), a basic libc and ld-acess
+   (dynamic linker).
+ /Usermode/include - Required include files for the shared libraries.
+
+=== Building ===
index a79952e..a87f329 100644 (file)
@@ -1,36 +1,27 @@
 # Project: Acess Shell\r
 \r
-CC = gcc\r
-AS = nasm\r
-LD = ld\r
-RM = @rm -f\r
+-include ../Makefile.cfg\r
 \r
-COBJ = main.o lib.o\r
-BIN = ../CLIShell\r
-ACESSDIR = /home/hodgeja/Projects/Acess2/Usermode\r
+CPPFLAGS += -I./include\r
+CFLAGS   += -Wall -fno-builtin -fno-stack-protector\r
+LDFLAGS  += \r
 \r
-INCS = -I$(ACESSDIR)/include -I./include\r
-CFLAGS = -Wall -fno-builtin -fno-stack-protector $(INCS)\r
-ASFLAGS = -felf\r
-LDFLAGS = -T $(ACESSDIR)/Libraries/acess.ld -I /Acess/Libs/ld-acess.so -lc\r
+BIN = ../CLIShell\r
+COBJ = main.o lib.o\r
 \r
 .PHONY : all clean\r
 \r
 all: $(BIN)\r
 \r
-$(BIN): $(AOBJ) $(COBJ)\r
+clean:\r
+       $(RM) $(COBJ) $(BIN)\r
+\r
+$(BIN): $(COBJ)\r
        @echo --- $(LD) -o $@\r
-       @$(LD) $(LDFLAGS) -o $@ $(AOBJ) $(COBJ) -Map Map.txt\r
+       @$(LD) $(LDFLAGS) -o $@ $(COBJ) -Map Map.txt\r
        objdump -d $(BIN) > $(BIN).dsm\r
-       cp $(BIN) /mnt/AcessHDD/Acess2/Bin/\r
-\r
-clean:\r
-       $(RM) $(AOBJ) $(COBJ) $(BIN)\r
+       cp $(BIN) $(DISTROOT)/Bin/\r
 \r
 $(COBJ): %.o: %.c\r
        @echo --- GCC -o $@\r
        @$(CC) $(CFLAGS) -c $? -o $@\r
-\r
-$(AOBJ): %.ao: %.asm\r
-       @echo --- $(AS) -o $@\r
-       @$(AS) $(ASFLAGS) -o $@ $<\r
diff --git a/Usermode/Applications/Makefile.cfg b/Usermode/Applications/Makefile.cfg
new file mode 100644 (file)
index 0000000..f8cd151
--- /dev/null
@@ -0,0 +1,9 @@
+# Acess 2 Applications
+# General Makefile
+
+-include ../../../Makefile.cfg
+
+ASFLAGS = -felf
+CPPFLAGS = -I../../include/
+CFLAGS   = -fno-stack-protector $(CPPFLAGS)
+LDFLAGS  = -T ../../Libraries/acess.ld -I /Acess/Libs/ld-acess.so -lc
index 5774e57..53b8edf 100644 (file)
@@ -1,18 +1,12 @@
 # Project: cat\r
 \r
-CC = gcc\r
-AS = nasm\r
-LD = ld\r
-RM = @rm -f\r
+-include ../Makefile.cfg\r
 \r
 COBJ = main.o
 BIN = ../cat\r
-ACESSDIR = /home/hodgeja/Projects/Acess2/Usermode\r
 \r
-INCS = -I$(ACESSDIR)/include -I./include\r
-CFLAGS = -Wall -fno-builtin -fno-stack-protector $(INCS)\r
-ASFLAGS = -felf\r
-LDFLAGS = -T $(ACESSDIR)/Libraries/acess.ld -I /Acess/Libs/ld-acess.so -lc\r
+CFLAGS  += -Wall -fno-builtin -fno-stack-protector\r
+LDFLAGS += \r
 \r
 .PHONY : all clean\r
 \r
@@ -22,7 +16,7 @@ $(BIN): $(COBJ)
        @echo --- $(LD) -o $@\r
        @$(LD) $(LDFLAGS) -o $@ $(COBJ) -Map Map.txt\r
        objdump -d $(BIN) > $(BIN).dsm\r
-       cp $(BIN) /mnt/AcessHDD/Acess2/Bin/\r
+       cp $(BIN) $(DISTROOT)/Bin/\r
 \r
 clean:\r
        $(RM) $(COBJ) $(BIN)\r
index a51f61b..0ec7739 100644 (file)
@@ -1,27 +1,24 @@
 #
-#
-#
 
-CC = gcc
-AS = nasm
-LD = ld
-RM = rm -f
+-include ../Makefile.cfg
 
-ASFLAGS = -felf
-CPPFLAGS = -nostdinc -I../../include
-CFLAGS = -Wall -Werror -O3 $(CPPFLAGS)
-LDFLAGS = -I/Acess/Libs/ld-acess.so -L../../Libraries ../../Libraries/crt0.o -lacess
+CPPFLAGS += 
+CFLAGS  += -Wall -Werror -O3
+LDFLAGS  += 
 
-OBJ = main.o
 BIN = ../init
+OBJ = main.o
 
 .PHONY: all clean
 
 all: $(BIN)
 
+clean:
+       $(RM) $(BIN) $(OBJ)
+
 $(BIN): $(OBJ) Makefile
        $(LD) $(LDFLAGS) $(OBJ) -o $(BIN)
-       cp $(BIN) /mnt/AcessHDD/Acess2/
+       cp $(BIN) $(DISTROOT)/SBin/
 
 %.o: %.c
        $(CC) $(CFLAGS) -c $< -o $@
index 83d9d7a..c09a174 100644 (file)
@@ -1,18 +1,12 @@
-#
-#
-#
+# Acess 2 Login Shell
 
-DBTYPE = tpl
+-include ../Makefile.cfg
 
-CC = gcc
-AS = nasm
-LD = ld
-RM = rm -f
+DBTYPE = tpl
 
-ASFLAGS = -felf
-CPPFLAGS = -I../../include
-CFLAGS = -fno-stack-protector -Wall -Werror -O3 $(CPPFLAGS)
-LDFLAGS = -I/Acess/Libs/ld-acess.so -L../../Libraries ../../Libraries/crt0.o -lacess -lgcc -lc
+CPPFLAGS += 
+CFLAGS   += -fno-stack-protector -Wall -Werror -O3 $(CPPFLAGS)
+LDFLAGS  += -lgcc -lc
 
 OBJ = main.o database_$(DBTYPE).o
 BIN = ../login
@@ -25,9 +19,11 @@ clean:
        $(RM) $(BIN) $(OBJ)
 
 $(BIN): $(OBJ)
-       $(LD) $(LDFLAGS) $(OBJ) -o $(BIN)
-       cp $(BIN) /mnt/AcessHDD/Acess2/SBin/
-       objdump -d ../login > login.dsm
+       @echo --- $(LD) -o $@
+       @$(LD) $(LDFLAGS) $(OBJ) -o $@
+       cp $(BIN) $(DISTROOT)/SBin/
+       objdump -d $(BIN) > login.dsm
 
 %.o: %.c Makefile
-       $(CC) $(CFLAGS) -c $< -o $@
+       @echo --- $(CC) -o $@
+       @$(CC) $(CFLAGS) -c $< -o $@
diff --git a/Usermode/Applications/login_src/header.h b/Usermode/Applications/login_src/header.h
new file mode 100644 (file)
index 0000000..695e1a9
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Acess2 Login Shell
+ */
+#ifndef _HEADER_H_
+#define _HEADER_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <acess/sys.h>
+
+// === TYPES ===
+typedef struct {
+        int    UID;
+        int    GID;
+       char    *Home;
+       char    *Shell;
+} tUserInfo;
+
+// === PROTOTYPES ===
+// --- User Database ---
+extern int     ValidateUser(char *Username, char *Password);
+extern tUserInfo       *GetUserInfo(int UID);
+
+#endif
diff --git a/Usermode/Applications/ls_src/Makefile b/Usermode/Applications/ls_src/Makefile
new file mode 100644 (file)
index 0000000..893dc55
--- /dev/null
@@ -0,0 +1,27 @@
+# Project: cat\r
+\r
+-include ../Makefile.cfg\r
+\r
+COBJ = main.o
+BIN = ../ls\r
+\r
+CFLAGS  += -Wall -fno-builtin\r
+LDFLAGS +=\r
+\r
+.PHONY : all clean\r
+\r
+all: $(BIN)\r
+\r
+$(BIN): $(COBJ)\r
+       @echo --- $(LD) -o $@\r
+       @$(LD) $(LDFLAGS) -o $@ $(COBJ) -Map Map.txt\r
+       objdump -d $(BIN) > $(BIN).dsm\r
+       cp $(BIN) $(DISTROOT)/Bin/\r
+\r
+clean:\r
+       $(RM) $(COBJ) $(BIN)\r
+\r
+$(COBJ): %.o: %.c\r
+       @echo --- GCC -o $@
+       @$(CC) $(CFLAGS) -c $? -o $@
+\r
diff --git a/Usermode/Applications/ls_src/main.c b/Usermode/Applications/ls_src/main.c
new file mode 100644 (file)
index 0000000..82f9c2a
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Acess2 LS command
+ */
+#include <acess/sys.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define        BUF_SIZE        1024
+
+// === PROTOTYPES ===
+ int   main(int argc, char *argv[]);
+void   ShowUsage(char *ProgName);
+void   ParseArguments(int argc, char *argv[]);
+void   SortFileList();
+
+// === GLOBALS ===
+// --- Flags ---
+ int   gbShowAll = 0;
+ int   gbShowImplicit = 0;
+ int   gbViewExtended = 0;
+ int   gbViewHumanReadable = 0;
+// --- Parameters ---
+char   *gsDirectory = NULL;
+// --- Working Set ---
+char   **gFileList;
+ int   giNumFiles = 0;
+
+/**
+ * \fn int main(int argc, char *argv[])
+ * \brief Entrypoint
+ */
+int main(int argc, char *argv[])
+{
+        int    fd, tmp;
+       char    buf[BUF_SIZE+1];
+       t_sysFInfo      info;
+        int    space = 0;
+
+       // Arguments Check
+       ParseArguments(argc, argv);
+
+       // Open Directory
+       fd = open(gsDirectory, OPENFLAG_READ|OPENFLAG_EXEC);
+       if(fd == -1) {
+               printf("Unable to open '%s' for reading\n", gsDirectory);
+               return EXIT_FAILURE;
+       }
+
+       // Check that it is a directory
+       finfo(fd, &info, 0);
+       if( !(info.flags & FILEFLAG_DIRECTORY) ) {
+               fprintf(stderr, "'%s' is a directory\n", gsDirectory);
+               close(fd);
+               return EXIT_FAILURE;
+       }
+
+       // Traverse Directory
+       while( (tmp = readdir(fd, buf)) )
+       {
+               // Error check
+               if(tmp < 0) {
+                       close(fd);
+                       return EXIT_FAILURE;
+               }
+               
+               // Allocate Space
+               if(space == giNumFiles)
+               {
+                       space += 16;
+                       gFileList = realloc(gFileList, space*sizeof(char*));
+                       if(gFileList == NULL) {
+                               close(fd);
+                               return EXIT_FAILURE;
+                       }
+               }
+               gFileList[giNumFiles++] = strdup(buf);
+       }
+
+       // Sort File List according to rules passed
+       SortFileList();
+
+       close(fd);
+       printf("\n");
+
+       return EXIT_SUCCESS;
+}
+
+/**
+ * \fn void ShowUsage(char *ProgName)
+ */
+void ShowUsage(char *ProgName)
+{
+       fprintf(stderr, "Usage: %s [options] [<directory>]\n", ProgName);
+       fprintf(stderr, "\n");
+}
+
+/**
+ * \fn void ParseArguments(int argc, char *argv[])
+ * \brief Parse the command line arguments
+ */
+void ParseArguments(int argc, char *argv[])
+{
+        int    i;
+       char    *str;
+       for( i = 1; i < argc; i ++ )
+       {
+               str = argv[i];
+               // Flags
+               if(str[0] == '-')
+               {
+                       if(str[1] == '-')
+                       {
+                               continue;
+                       }
+                       str = &str[1];
+                       for( ; *str; str++ )
+                       {
+                               switch(*str)
+                               {
+                               // Show All
+                               case 'a':       gbShowAll = 1;  gbShowImplicit = 1;     continue;
+                               // Almost All
+                               case 'A':       gbShowAll = 1;  gbShowImplicit = 0;     continue;
+                               // Extended List
+                               case 'l':       gbViewExtended = 1;     continue;
+                               // Human readable sizes
+                               case 'h':       gbViewHumanReadable = 1;        continue;
+                               default:
+                                       fprintf(stderr, "%s: Unknown option '%c'\n", *str);
+                                       ShowUsage(argv[0]);
+                                       exit(EXIT_FAILURE);
+                               }
+                       }
+                       continue;
+               }
+               
+               if(gsDirectory == NULL) {
+                       gsDirectory = argv[i];
+               }
+       }
+       
+       // Apply Defaults
+       if(!gsDirectory)        gsDirectory = ".";
+       
+       printf("gsDirectory = '%s'\n", gsDirectory);
+}
+
+/**
+ * \fn int strcmpp(void *p1, void *p2)
+ * \brief Compares two strings given pointers to their pointers
+ */
+int strcmpp(const void *p1, const void *p2)
+{
+       return strcmp( *(char **)p1, *(char **)p2 );
+}
+
+/**
+ * \fn void SortFileList()
+ * \brief Sorts the filled file list
+ */
+void SortFileList()
+{
+       qsort(gFileList, giNumFiles, sizeof(char*), strcmpp);
+}
diff --git a/Usermode/Libraries/Makefile.cfg b/Usermode/Libraries/Makefile.cfg
new file mode 100644 (file)
index 0000000..2e09392
--- /dev/null
@@ -0,0 +1,9 @@
+# Acess 2 Libraries
+# General Makefile
+
+-include ../../../Makefile.cfg
+
+ASFLAGS  = -felf
+CPPFLAGS = -I../../include/
+CFLAGS   = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)
+LDFLAGS  = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain -x -L.. -lacess
index 2d00516..6349091 100644 (file)
@@ -2,22 +2,15 @@
 #  LD-ACESS.SO\r
 #  Makefile\r
 \r
-CC = gcc\r
-AS = nasm\r
-RM = @rm -f\r
-LD = ld\r
-OBJDUMP = objdump\r
+-include ../Makefile.cfg\r
 \r
 COBJ = main.o lib.o loadlib.o elf.o pe.o\r
 AOBJ = helpers.ao\r
 BIN = ../ld-acess.so\r
 \r
-CPPFLAGS = -I../../include\r
-CFLAGS = -Wall -fno-builtin -fleading-underscore -fno-stack-protector\r
-ASFLAGS = -felf\r
-#LDFLAGS = --oformat elf32-i386 -Map map.txt -Bstatic -e _SoMain -shared\r
-#LDFLAGS = --oformat elf32-i386 -Map map.txt -Bstatic -e _SoMain -Ttext 0xBFFFE000\r
-LDFLAGS = -T link.ld -Map map.txt -Bstatic\r
+CFLAGS   = -Wall -fno-builtin -fleading-underscore -fno-stack-protector\r
+ASFLAGS  = -felf\r
+LDFLAGS  = -T link.ld -Map map.txt -Bstatic\r
 \r
 \r
 .PHONY: all clean\r
@@ -28,14 +21,17 @@ clean:
        $(RM) $(BIN) $(AOBJ) $(COBJ)\r
 \r
 $(BIN): $(AOBJ) $(COBJ)\r
-       $(LD) $(LDFLAGS) -o $(BIN) $(AOBJ) $(COBJ) > link.txt\r
+       @echo --- $(LD) -shared -o $@\r
+       @$(LD) $(LDFLAGS) -o $(BIN) $(AOBJ) $(COBJ) > link.txt\r
        $(OBJDUMP) -x $(BIN) > ld-acess.dmp\r
        $(OBJDUMP) -d $(BIN) > ld-acess.dsm\r
-       cp $(BIN) /mnt/AcessHDD/Acess2/Libs\r
+       cp $(BIN) $(DISTROOT)/Libs\r
 \r
 $(COBJ): %.o: %.c\r
-       $(CC) $(CFLAGS) -o $@ -c $<\r
+       @echo $(CC) -o $@\r
+       @$(CC) $(CFLAGS) -o $@ -c $<\r
 \r
 $(AOBJ): %.ao: %.asm\r
-       $(AS) $(ASFLAGS) -o $@ $<\r
+       @echo $(AS) -o $@\r
+       @$(AS) $(ASFLAGS) -o $@ $<\r
        
diff --git a/Usermode/Libraries/ld-acess.so_src/helpers.asm b/Usermode/Libraries/ld-acess.so_src/helpers.asm
new file mode 100644 (file)
index 0000000..eb275ee
--- /dev/null
@@ -0,0 +1,58 @@
+; AcessOS 1\r
+; By thePowersGang\r
+; LD-ACESS.SO\r
+; - helpers.asm\r
+\r
+%include "../libacess.so_src/syscalls.inc.asm"\r
+\r
+[global _SysDebug]\r
+[global _SysExit]\r
+[global _SysLoadBin]\r
+[global _SysUnloadBin]\r
+\r
+; void SysDebugV(char *fmt, va_list Args)\r
+_SysDebug:\r
+       ;xchg bx, bx\r
+       push ebp\r
+       mov ebp, esp\r
+       pusha\r
+       \r
+       mov eax, 0x100  ; User Debug\r
+       mov ebx, [ebp+8]        ; Format\r
+       mov ecx, [ebp+12]       ; Arguments\r
+       mov edx, [ebp+16]       ; Arguments\r
+       mov edi, [ebp+20]       ; Arguments\r
+       mov esi, [ebp+24]       ; Arguments\r
+       int     0xAC\r
+       \r
+       popa\r
+       pop ebp\r
+       ret\r
+\r
+; void SysExit()\r
+_SysExit:\r
+       push ebx\r
+       mov eax, SYS_EXIT       ; Exit\r
+       mov ebx, [esp+0x8]      ; Exit Code\r
+       int     0xAC\r
+       pop ebx\r
+       ret\r
+\r
+; Uint SysLoadBin(char *path, Uint *entry)\r
+_SysLoadBin:\r
+       push ebx\r
+       mov eax, SYS_LOADBIN    ; SYS_LDBIN\r
+       mov ebx, [esp+0x8]      ; Path\r
+       mov ecx, [esp+0xC]      ; Entry\r
+       int     0xAC\r
+       pop ebx\r
+       ret\r
+\r
+; Uint SysUnloadBin(Uint Base)\r
+_SysUnloadBin:\r
+       push ebx\r
+       mov eax, SYS_UNLOADBIN  ; SYS_ULDBIN\r
+       mov ebx, [esp+0x8]      ; Base\r
+       int     0xAC\r
+       pop ebx\r
+       ret\r
diff --git a/Usermode/Libraries/ld-acess.so_src/link.ld b/Usermode/Libraries/ld-acess.so_src/link.ld
new file mode 100644 (file)
index 0000000..8ddc234
--- /dev/null
@@ -0,0 +1,27 @@
+ENTRY(_SoMain)\r
+OUTPUT_FORMAT(elf32-i386)\r
+\r
+SECTIONS {\r
+    . = 0xBBFF0000;\r
+       _gLinkedBase = .;\r
+\r
+   .text : AT(ADDR(.text)) {\r
+        code = .;\r
+        *(.text)\r
+        *(.rodata*)\r
+   }\r
+\r
+   .data ALIGN (0x1000) : AT(ADDR(.data)) {\r
+        data = .;\r
+        *(.data)\r
+   }\r
+\r
+   .bss ALIGN (0x1000) : AT(ADDR(.bss)) {\r
+        _sbss = .;\r
+        *(COMMON)\r
+        *(.bss)\r
+        _ebss = .;\r
+        bss = .;\r
+   }\r
+   _end = .;\r
+}
index 7b320b9..3118cb6 100644 (file)
@@ -2,10 +2,7 @@
 #
 #
 
-AS = nasm
-LD = ld
-STRIP = strip
-RM = rm -f
+-include ../../../Makefile.cfg
 
 ASFLAGS = -felf
 LDFLAGS = -nostdlib -shared -I/Acess/Libs/ld-acess.so -e SoMain
@@ -21,9 +18,11 @@ clean:
        $(RM) $(BIN) $(OBJ)
 
 $(BIN): $(OBJ)
-       $(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
+       @echo --- $(LD) -shared -o $@
+       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ)
        $(STRIP) $(BIN)
-       cp $(BIN) /mnt/AcessHDD/Acess2/Libs
+       cp $(BIN) $(DISTROOT)/Libs
        
 %.ao: %.asm syscalls.inc.asm
-       $(AS) $(ASFLAGS) -o $@ $<
+       @echo $(AS) -o $@
+       @$(AS) $(ASFLAGS) -o $@ $<
index fd186a9..c2979a0 100644 (file)
@@ -1,19 +1,15 @@
-# AcessOS Basic C Library\r
+# Acess2 Basic C Library\r
 # Makefile\r
 \r
-CC = gcc\r
-AS = nasm\r
-RM = @rm -f\r
-LD = ld\r
-OBJDUMP = objdump\r
-ACESSDIR = /home/hodgeja/Projects/Acess2\r
+-include ../Makefile.cfg\r
 \r
-CPPFLAGS = -I$(ACESSDIR)/Usermode/include\r
-CFLAGS = -Wall -fPIC -fno-builtin -fno-stack-protector $(CPPFLAGS)\r
-ASFLAGS = -felf\r
-LDFLAGS = -x -shared -soname libc.so.1 -Map map.txt -e SoMain -L$(ACESSDIR)/Usermode/Libraries -lacess\r
+CPPFLAGS += \r
+CFLAGS   += \r
+ASFLAGS  +=\r
+LDFLAGS  += -soname libc.so.1 -Map map.txt\r
 \r
-OBJ_LIBC = heap.o stdlib.o stub.o env.o fileIO.o signals.o string.o\r
+OBJ_LIBC = heap.o stdlib.o stub.o env.o fileIO.o string.o\r
+# signals.o\r
 BIN = ../libc.so.1\r
 \r
 .PHONY:        all clean\r
@@ -30,7 +26,7 @@ $(BIN): $(OBJ_LIBC)
        $(OBJDUMP) -d $@ > libc.so.1.dsm\r
        $(OBJDUMP) -x -r -R $@ > libc.so.1.dmp\r
        cp ../libc.so.1 ../libc.so\r
-       cp ../libc.so.1 /mnt/AcessHDD/Acess2/Libs/\r
+       cp ../libc.so.1 $(DISTROOT)/Libs/\r
 \r
 # C Runtime 0\r
 ../crt0.o: crt0.asm\r
diff --git a/Usermode/Libraries/libc.so_src/config.h b/Usermode/Libraries/libc.so_src/config.h
new file mode 100644 (file)
index 0000000..fe3343e
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * AcessOS Standard C Library
+ * CONFIG.H
+ * Configuration Options
+ */
+#ifndef _CONFIG_H
+# define _CONFIG_H
+
+// -- COMMON --
+#define        _LIBC_BUILD     1
+#define DEBUG_BUILD    0
+
+// -- STDIO --
+#define STDIO_MAX_STREAMS      64
+#define STDIO_LOCAL_BUFFER     0
+
+#endif
diff --git a/Usermode/Libraries/libc.so_src/crt0.asm b/Usermode/Libraries/libc.so_src/crt0.asm
new file mode 100644 (file)
index 0000000..e61a44c
--- /dev/null
@@ -0,0 +1,9 @@
+; AcessOS LibC\r
+; crt0.asm\r
+;\r
+\r
+[extern _heap_start]\r
+\r
+start:\r
+       \r
+       \r
diff --git a/Usermode/Libraries/libc.so_src/lib.h b/Usermode/Libraries/libc.so_src/lib.h
new file mode 100644 (file)
index 0000000..9d5194b
--- /dev/null
@@ -0,0 +1,19 @@
+/*\r
+AcessOS Basic Lib C\r
+\r
+lib.h\r
+*/\r
+#ifndef _LIB_H\r
+#define _LIB_H\r
+\r
+#define BUILD_SO       1\r
+\r
+#if defined(BUILD_DLL)\r
+#define        EXPORT  __declspec(dllexport)\r
+#define        LOCAL\r
+#elif defined(BUILD_SO)\r
+#define        EXPORT\r
+#define        LOCAL\r
+#endif\r
+\r
+#endif\r
diff --git a/Usermode/Libraries/libc.so_src/stdio_int.h b/Usermode/Libraries/libc.so_src/stdio_int.h
new file mode 100644 (file)
index 0000000..5bfbf98
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * AcessOS Standard C Library
+ * SDTIO_INT.H
+ * Configuration Options
+ */
+#ifndef _STDIO_INT_H
+# define _STDIO_INT_H
+
+// === CONSTANTS ===
+#define FILE_FLAG_MODE_MASK    0x07
+#define FILE_FLAG_MODE_READ            0x01
+#define FILE_FLAG_MODE_WRITE   0x02
+#define FILE_FLAG_MODE_EXEC            0x03
+#define FILE_FLAG_MODE_APPEND  0x04
+#define FILE_FLAG_M_EXT                0x10
+
+// === TYPES ===
+struct sFILE {
+        int    FD;
+        int    Flags;
+       #if DEBUG_BUILD
+       char    *FileName;
+       #endif
+       #if STDIO_LOCAL_BUFFER
+       char    *Buffer;
+       Uint64  BufferStart;
+        int    BufferSize;
+       #endif
+};
+
+#endif
diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c
new file mode 100644 (file)
index 0000000..07c2017
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * AcessOS Basic C Library
+ * string.c
+ */
+#include <acess/sys.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lib.h"
+
+/**
+ * \fn EXPORT int strcmp(const char *s1, const char *s2)
+ * \brief Compare two strings
+ */
+EXPORT int strcmp(const char *s1, const char *s2)
+{
+       while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
+               s1++; s2++;
+       }
+       return (int)*s1 - (int)*s2;
+}
+
+/**
+ * \fn EXPORT char *strcpy(char *dst, const char *src)
+ * \brief Copy a string to another
+ */
+EXPORT char *strcpy(char *dst, const char *src)
+{
+       char *_dst = dst;
+       while(*src) {
+               *dst = *src;
+               src++; dst++;
+       }
+       *dst = '\0';
+       return _dst;
+}
+
+/**
+ * \fn EXPORT int strlen(const char *str)
+ * \brief Get the length of a string
+ */
+EXPORT int strlen(const char *str)
+{
+       int retval;
+       for(retval = 0; *str != '\0'; str++)
+               retval++;
+       return retval;
+}
+
+/**
+ * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t len)
+ * \brief Compare two strings with a limit
+ */
+EXPORT int strncmp(const char *s1, const char *s2, size_t len)
+{
+       while(--len && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
+               s1++; s2++;
+       }
+       return (int)*s1 - (int)*s2;
+}
+
+/**
+ * \fn EXPORT char *strdup(const char *str)
+ * \brief Duplicate a string using heap memory
+ * \note Defined in POSIX Spec, not C spec
+ */
+EXPORT char *strdup(const char *str)
+{
+       size_t  len = strlen(str);
+       char    *ret = malloc(len+1);
+       if(ret == NULL) return NULL;
+       strcpy(ret, str);
+       return ret;
+}
+
+// --- Memory ---
+/**
+ * \fn EXPORT void *memset(void *dest, int val, size_t num)
+ * \brief Clear memory with the specified value
+ */
+EXPORT void *memset(void *dest, int val, size_t num)
+{
+       unsigned char *p = dest;
+       while(num--)    *p++ = val;
+       return dest;
+}
+
+/**
+ * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
+ * \brief Copy one memory area to another
+ */
+EXPORT void *memcpy(void *dest, const void *src, size_t count)
+{
+    char *sp = (char *)src;
+    char *dp = (char *)dest;
+    for(;count--;) *dp++ = *sp++;
+    return dest;
+}
+
+/**
+ * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
+ * \brief Copy data in memory, avoiding overlap problems
+ */
+EXPORT void *memmove(void *dest, const void *src, size_t count)
+{
+    char *sp = (char *)src;
+    char *dp = (char *)dest;
+       // Check if corruption will happen
+       if( (unsigned int)dest > (unsigned int)src && (unsigned int)dest < (unsigned int)src+count )
+               for(;count--;) dp[count] = sp[count];
+       else
+       for(;count--;) *dp++ = *sp++;
+    return dest;
+}
diff --git a/Usermode/Libraries/libgcc.so_src/Makefile b/Usermode/Libraries/libgcc.so_src/Makefile
new file mode 100644 (file)
index 0000000..ada47db
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# libgcc
+#
+
+-include ../Makefile.cfg
+
+OBJS = libgcc.o
+BIN = ../libgcc.so
+
+CFLAGS  += -Wall -Werror
+LDFLAGS += -soname libgcc.acess.so
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+       $(RM) $(BIN) $(OBJS)
+
+$(BIN): $(OBJS)
+       @echo -- ld -o $@
+       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJS)
+       @$(OBJDUMP) -d $(BIN) > libgcc.so.dsm
+       cp $(BIN) $(DISTROOT)/Libs
+
+$(OBJS): %.o: %.c
+       @echo -- gcc -o $@
+       @$(CC) $(CFLAGS) -o $@ -c $<
diff --git a/Usermode/Libraries/libgcc.so_src/libgcc.c b/Usermode/Libraries/libgcc.so_src/libgcc.c
new file mode 100644 (file)
index 0000000..2127b55
--- /dev/null
@@ -0,0 +1,50 @@
+/* Acess GCC Helper Library
+ *
+ */
+#include <sys/sys.h>
+
+typedef unsigned long long int uint64_t;
+
+// === CODE ===
+int SoMain()
+{
+       return 0;
+}
+
+// --- Errors ---
+void __stack_chk_fail()
+{
+       write(1, 32, "FATAL ERROR: Stack Check Failed\n");
+       _exit(-1);
+       for(;;);
+}
+
+// --- 64-Bit Math ---
+/**
+ * \fn uint64_t __udivdi3(uint64_t Num, uint64_t Den)
+ * \brief Divide two 64-bit integers
+ */
+uint64_t __udivdi3(uint64_t Num, uint64_t Den)
+{
+       uint64_t        ret = 0;
+       if(Den == 0)    // Call Div by Zero Error
+               __asm__ __volatile__ ("int $0");
+       while(Num > Den) {
+               ret ++;
+               Num -= Den;
+       }
+       return ret;
+}
+
+/**
+ * \fn uint64_t __umoddi3(uint64_t Num, uint64_t Den)
+ * \brief Get the modulus of two 64-bit integers
+ */
+uint64_t __umoddi3(uint64_t Num, uint64_t Den)
+{
+       if(Den == 0)    // Call Div by Zero Error
+               __asm__ __volatile__ ("int $0");
+       while(Num > Den)
+               Num -= Den;
+       return Num;
+}
diff --git a/Usermode/include/string.h b/Usermode/include/string.h
new file mode 100644 (file)
index 0000000..158aeeb
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * AcessOS LibC
+ * string.h
+ */
+#ifndef __STRING_H
+#define __STRING_H
+
+// Memory
+extern void *memset(void *dest, int val, size_t count);
+extern void *memcpy(void *dest, const void *src, size_t count);
+extern void *memmove(void *dest, const void *src, size_t count);
+extern int     memcmp(const void *mem1, const void *mem2, size_t count);
+
+// Strings
+extern int     strlen(const char *string);
+extern int     strcmp(const char *str1, const char *str2);
+extern int     strncmp(const char *str1, const char *str2, size_t len);
+extern char    *strcpy(char *dst, const char *src);
+extern char    *strdup(const char *src);
+
+#endif

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