Various Changes
authorJohn Hodge <[email protected]>
Thu, 15 Oct 2009 13:30:48 +0000 (21:30 +0800)
committerJohn Hodge <[email protected]>
Thu, 15 Oct 2009 13:30:48 +0000 (21:30 +0800)
- Double fault protection
- Optomised Memory Functions (also added memcmp)
- Added worker threads
- Fixes to the timer code (stop the RTC firing at 1024 Hz)
- Re-included the FDD driver
- Moved the NE2000 driver to /Modules
- Inconcequential changes to system.c
- Added block allocation to fs/ext2
- Changed the makefiles to support static linking of modules

17 files changed:
Kernel/Makefile
Kernel/arch/x86/desctab.asm
Kernel/arch/x86/errors.c
Kernel/arch/x86/include/mm_virt.h
Kernel/arch/x86/lib.c
Kernel/arch/x86/mm_phys.c
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.c
Kernel/arch/x86/time.c
Kernel/drv/fdd.c
Kernel/drv/ne2000.c [deleted file]
Kernel/include/common.h
Kernel/lib.c
Kernel/system.c
Kernel/threads.c
Kernel/vfs/fs/ext2.c
Makefile.cfg

index 195d311..5aeee68 100644 (file)
@@ -19,10 +19,12 @@ OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
 OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o drvutil.o
 OBJ += binary.o bin/elf.o
 OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o
-OBJ += vfs/fs/root.o vfs/fs/devfs.o vfs/fs/fat.o vfs/fs/ext2.o
+OBJ += vfs/fs/root.o vfs/fs/devfs.o
+OBJ += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
 OBJ += drv/fifo.o drv/dma.o drv/pci.o drv/vterm.o drv/vga.o drv/kb.o
 OBJ += $(addprefix drv/, $(addsuffix .o,$(DRIVERS)))
 OBJ := $(addsuffix .$(ARCH), $(OBJ))
+MODS += $(addprefix ../Modules/, $(addsuffix .o.$(ARCH),$(MODULES)))
 BIN = ../Acess2.$(ARCH).bin
 
 DEPFILES  = $(filter %.o.$(ARCH),$(OBJ))
@@ -38,9 +40,9 @@ all: $(BIN)
 clean:
        @$(RM) $(BIN) $(OBJ) $(DEPFILES)
 
-$(BIN): $(OBJ) arch/$(ARCHDIR)/link.ld Makefile
+$(BIN): $(OBJ) $(MODS) arch/$(ARCHDIR)/link.ld Makefile
        @echo --- LD -o $(BIN)
-       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) -Map ../Map.$(ARCH).txt
+       @$(LD) $(LDFLAGS) -o $(BIN) $(OBJ) $(MODS) -Map ../Map.$(ARCH).txt
        @objdump $(BIN) -D > $(BIN).dsm
        cp $(BIN) $(DISTROOT)
        @wc -l $(SRCFILES) > LineCounts.$(ARCH).txt
@@ -51,9 +53,13 @@ $(BIN): $(OBJ) arch/$(ARCHDIR)/link.ld Makefile
        @$(AS) $(ASFLAGS) $< -o $@
 
 %.o.$(ARCH): %.c Makefile
+#      if exists %*/Makefile
+#      @make -C %*/ all
+#      else
        @echo --- GCC -o $@
        @$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
        @$(MAKEDEP) $(CPPFLAGS) -MT $@ -o $*.d.$(ARCH) $<
+#      endif
 
 include/syscalls.h:    syscalls.lst Makefile
        php GenSyscalls.php
index 2d0a232..f403950 100644 (file)
@@ -8,7 +8,7 @@ MAX_CPUS        equ     1
 %else
 MAX_CPUS       equ     8
 %endif
-GDT_SIZE       equ     (1+2*2+MAX_CPUS)*8      ; 4 Permission levels
+GDT_SIZE       equ     (1+2*2+1+MAX_CPUS)*8
 
 [section .data]
 ; GDT
@@ -21,6 +21,7 @@ _gGDT:
        dd 0x0000FFFF, 0x00CF9200       ; 10 PL0 Data
        dd 0x0000FFFF, 0x00CFFA00       ; 18 PL3 Code
        dd 0x0000FFFF, 0x00CFF200       ; 20 PL3 Data
+       dd 0, 0 ; Double Fault TSS
        times MAX_CPUS  dd 0, 0
 _gGDTptr:
        dw      GDT_SIZE-1
index 0c2da16..b9ff17d 100644 (file)
@@ -4,6 +4,7 @@
  * - CPU Error Handler
  */
 #include <common.h>
+#include <proc.h>
 
 // === CONSTANTS ===
 #define        MAX_BACKTRACE   8       //!< Maximum distance to trace the stack backwards
index 8b7508c..d3260fe 100644 (file)
@@ -1,9 +1,9 @@
 /*
- * AcessOS Microkernel Version
- * mm_phys.h
+ * Acess2
+ * - Virtual Memory Manager (Header)
  */
-#ifndef _MM_PHYS_H
-#define _MM_PHYS_H
+#ifndef _MM_VIRT_H
+#define _MM_VIRT_H
 
 // === FUNCTIONS ===
 extern void    MM_SetCR3(Uint32 CR3);
@@ -12,5 +12,6 @@ extern void   MM_Deallocate(Uint VAddr);
 extern int     MM_Map(Uint VAddr, tPAddr PAddr);
 extern Uint    MM_Clone();
 extern Uint    MM_NewKStack();
+extern Uint    MM_NewWorkerStack();
 
 #endif
index 6b9ee1e..1bbdeab 100644 (file)
@@ -70,11 +70,25 @@ void *memsetd(void *Dest, Uint Val, Uint Num)
        return Dest;
 }
 
+/**
+ * \fn int memcmp(const void *m1, const void *m2, Uint Num)
+ * \brief Compare two pieces of memory
+ */
+int memcmp(const void *m1, const void *m2, Uint Num)
+{
+       while(Num--)
+       {
+               if(*(Uint8*)m1 != *(Uint8*)m2)  break;
+               m1 ++;
+               m2 ++;
+       }
+       return *(Uint8*)m1 - *(Uint8*)m2;
+}
 
 /**
  * \fn void *memcpy(void *Dest, void *Src, Uint Num)
  */
-void *memcpy(void *Dest, void *Src, Uint Num)
+void *memcpy(void *Dest, const void *Src, Uint Num)
 {
        if((Uint)Dest & 3 || (Uint)Src & 3)
                __asm__ __volatile__ ("rep movsb" :: "D" (Dest), "S" (Src), "c" (Num));
@@ -90,7 +104,7 @@ void *memcpy(void *Dest, void *Src, Uint Num)
 /**
  * \fn void *memcpyd(void *Dest, void *Src, Uint Num)
  */
-void *memcpyd(void *Dest, void *Src, Uint Num)
+void *memcpyd(void *Dest, const void *Src, Uint Num)
 {
        __asm__ __volatile__ ("rep movsl" :: "D" (Dest), "S" (Src), "c" (Num));
        return Dest;
@@ -154,6 +168,15 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den)
        return Num;
 }
 
+Uint16 LittleEndian16(Uint16 Val)
+{
+       return Val;
+}
+Uint16 BigEndian16(Uint16 Val)
+{
+       return ((Val&0xFF)<<8) | ((Val>>8)&0xFF);
+}
+
 // --- EXPORTS ---
 EXPORT(memcpy);        EXPORT(memset);
 //EXPORT(memcpyw);     EXPORT(memsetw);
index 4c5cf20..82c45c3 100644 (file)
@@ -1,7 +1,7 @@
 /*
- AcessOS Microkernel Version
- mm_phys.c
-*/
+ * Acess2
+ * - Physical memory manager
+ */
 #define DEBUG  1
 #include <common.h>
 #include <mboot.h>
index c930947..f5b8959 100644 (file)
 #include <mm_phys.h>
 #include <proc.h>
 
-#define KERNEL_STACKS  0xF0000000
+#define KERNEL_STACKS          0xF0000000
 #define        KERNEL_STACK_SIZE       0x00002000
-#define KERNEL_STACK_END       0xFD000000
+#define KERNEL_STACKS_END      0xFD000000
+#define WORKER_STACKS          0x00100000      // Thread0 Only!
+#define        WORKER_STACK_SIZE       KERNEL_STACK_SIZE
+#define WORKER_STACKS_END      0xB0000000
+#define        NUM_WORKER_STACKS       ((WORKER_STACKS_END-WORKER_STACKS)/WORKER_STACK_SIZE)
 #define PAGE_TABLE_ADDR        0xFD000000
 #define PAGE_DIR_ADDR  0xFD3F4000
 #define PAGE_CR3_ADDR  0xFD3F4FD0
@@ -58,6 +62,9 @@ tPAddr        *gaTmpTable = (void*)TMP_TABLE_ADDR;
 tPAddr *gaTmpDir = (void*)TMP_DIR_ADDR;
 tPAddr *gTmpCR3 = (void*)TMP_CR3_ADDR;
  int   gilTempMappings = 0;
+ int   gilTempFractal = 0;
+Uint32 gWorkerStacks[NUM_WORKER_STACKS/32];
+ int   giLastUsedWorker = 0;
 
 // === CODE ===
 /**
@@ -83,7 +90,7 @@ void MM_InstallVirtual()
        {
                if( gaPageDir[ i ] )    continue;
                // Skip stack tables, they are process unique
-               if( i > KERNEL_STACKS >> 22 && i < KERNEL_STACK_END >> 22) {
+               if( i > KERNEL_STACKS >> 22 && i < KERNEL_STACKS_END >> 22) {
                        gaPageDir[ i ] = 0;
                        continue;
                }
@@ -128,6 +135,12 @@ void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs)
        
        // If it was a user, tell the thread handler
        if(ErrorCode & 4) {
+               Warning("%s %s %s memory%s",
+                       (ErrorCode&4?"User":"Kernel"),
+                       (ErrorCode&2?"write to":"read from"),
+                       (ErrorCode&1?"bad/locked":"non-present"),
+                       (ErrorCode&16?" (Instruction Fetch)":"")
+                       );
                Warning("User Pagefault: Instruction at %p accessed %p", Regs->eip, Addr);
                __asm__ __volatile__ ("sti");   // Restart IRQs
                Threads_SegFault(Addr);
@@ -417,11 +430,12 @@ Uint MM_ClearUser()
 Uint MM_Clone()
 {
        Uint    i, j;
+       Uint    ret;
        Uint    page = 0;
        Uint    kStackBase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE;
        void    *tmp;
        
-       //ENTER("");
+       LOCK( &gilTempFractal );
        
        // Create Directory Table
        *gTmpCR3 = MM_AllocPhys() | 3;
@@ -484,7 +498,7 @@ Uint MM_Clone()
        
        // Allocate kernel stack
        for(i = KERNEL_STACKS >> 22;
-               i < KERNEL_STACK_END >> 22;
+               i < KERNEL_STACKS_END >> 22;
                i ++ )
        {
                // Check if directory is allocated
@@ -528,8 +542,11 @@ Uint MM_Clone()
                }
        }
        
-       //LEAVE('x', *gTmpCR3 & ~0xFFF);
-       return *gTmpCR3 & ~0xFFF;
+       ret = *gTmpCR3 & ~0xFFF;
+       RELEASE( &gilTempFractal );
+       
+       //LEAVE('x', ret);
+       return ret;
 }
 
 /**
@@ -540,7 +557,7 @@ Uint MM_NewKStack()
 {
        Uint    base = KERNEL_STACKS;
        Uint    i;
-       for(;base<KERNEL_STACK_END;base+=KERNEL_STACK_SIZE)
+       for(;base<KERNEL_STACKS_END;base+=KERNEL_STACK_SIZE)
        {
                if(MM_GetPhysAddr(base) != 0)   continue;
                for(i=0;i<KERNEL_STACK_SIZE;i+=0x1000) {
@@ -552,6 +569,99 @@ Uint MM_NewKStack()
        return 0;
 }
 
+/**
+ * \fn Uint MM_NewWorkerStack()
+ * \brief Creates a new worker stack
+ */
+Uint MM_NewWorkerStack()
+{
+       Uint    esp, ebp;
+       Uint    oldstack;
+       Uint    base, addr;
+        int    i, j;
+       Uint    *tmpPage;
+       tPAddr  pages[WORKER_STACK_SIZE>>12];
+       
+       // Get the old ESP and EBP
+       __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
+       __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
+       
+       // Find a free worker stack address
+       for(base = giLastUsedWorker; base < NUM_WORKER_STACKS; base++)
+       {
+               // Used block
+               if( gWorkerStacks[base/32] == -1 ) {
+                       base += 31;     base &= ~31;
+                       base --;        // Counteracted by the base++
+                       continue;
+               }
+               // Used stack
+               if( gWorkerStacks[base/32] & (1 << base) ) {
+                       continue;
+               }
+       }
+       if(base >= NUM_WORKER_STACKS) {
+               Warning("Uh-oh! Out of worker stacks");
+               return 0;
+       }
+       
+       // It's ours now!
+       gWorkerStacks[base/32] |= (1 << base);
+       // Make life easier for later calls
+       giLastUsedWorker = base;
+       // We have one
+       base = WORKER_STACKS + base * WORKER_STACK_SIZE;
+       
+       // Acquire the lock for the temp fractal mappings
+       LOCK(&gilTempFractal);
+       
+       // Set the temp fractals to TID0's address space
+       *gTmpCR3 = (Uint)gaInitPageDir | 3;
+       INVLPG( gaTmpDir );
+       
+       // Check if the directory is mapped (we are assuming that the stacks
+       // will fit neatly in a directory
+       if(gaTmpDir[ base >> 22 ] == 0) {
+               gaTmpDir[ base >> 22 ] = MM_AllocPhys() | 3;
+               INVLPG( &gaTmpTable[ (base>>22) & ~0x3FF ] );
+       }
+       
+       // Mapping Time!
+       for( addr = 0; addr < WORKER_STACK_SIZE; addr += 0x1000 )
+       {
+               pages[ addr >> 12 ] = MM_AllocPhys();
+               gaTmpTable[ (base + addr) >> 12 ] = pages[addr>>12] | 3;
+       }
+       // Release the temp mapping lock
+       RELEASE(&gilTempFractal);
+       
+       // Copy the old stack
+       oldstack = (esp + KERNEL_STACK_SIZE-1) & ~(KERNEL_STACK_SIZE-1);
+       esp = oldstack - esp;   // ESP as an offset in the stack
+       
+       i = (WORKER_STACK_SIZE>>12) - 1;
+       // Copy the contents of the old stack to the new one, altering the addresses
+       // `addr` is refering to bytes from the stack base (mem downwards)
+       for(addr = 0; addr < esp; addr += 0x1000)
+       {
+               Uint    *stack = (Uint*)( oldstack-(addr+0x1000) );
+               tmpPage = (void*)MM_MapTemp( pages[i] );
+               // Copy old stack
+               for(j = 0; j < 1024; j++)
+               {
+                       // Possible Stack address?
+                       if(oldstack-esp < stack[j] && stack[j] < oldstack)
+                               tmpPage[j] = base - (oldstack - stack[j]);
+                       else    // Seems not, best leave it alone
+                               tmpPage[j] = stack[j];
+               }
+               MM_FreeTemp((Uint)tmpPage);
+               i --;
+       }
+       
+       return base;
+}
+
 /**
  * \fn void MM_SetFlags(Uint VAddr, Uint Flags, Uint Mask)
  * \brief Sets the flags on a page
index f7bda0f..5132f82 100644 (file)
@@ -34,6 +34,7 @@ extern tThread        *gDeleteThreads;
 extern tThread *Threads_GetNextToRun(int CPU);
 extern void    Threads_Dump();
 extern tThread *Threads_CloneTCB(Uint *Err, Uint Flags);
+extern void    Isr7();
 
 // === PROTOTYPES ===
 void   ArchThreads_Init();
@@ -60,6 +61,13 @@ tTSS *gTSSs = NULL;
 #if !USE_MP
 tTSS   gTSS0 = {0};
 #endif
+// --- Error Recovery ---
+char   gaDoubleFaultStack[1024];
+tTSS   gDoubleFault_TSS = {
+       .ESP0 = (Uint)&gaDoubleFaultStack[1023],
+       .SS0 = 0x10,
+       .EIP = (Uint)Isr7
+};
 
 // === CODE ===
 /**
@@ -106,6 +114,15 @@ void ArchThreads_Init()
        #if USE_MP
        }
        
+       // Initialise Double Fault TSS
+       gGDT[5].LimitLow = sizeof(tTSS);
+       gGDT[5].LimitHi = 0;
+       gGDT[5].Access = 0x89;  // Type
+       gGDT[5].Flags = 0x4;
+       gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF;
+       gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
+       gGDT[5].BaseHi = (Uint)&gDoubleFault_TSS >> 24;
+       
        // Initialise TSS
        for(pos=0;pos<giNumCPUs;pos++)
        {
@@ -114,18 +131,18 @@ void ArchThreads_Init()
        #endif
                gTSSs[pos].SS0 = 0x10;
                gTSSs[pos].ESP0 = 0;    // Set properly by scheduler
-               gGDT[5+pos].LimitLow = sizeof(tTSS);
-               gGDT[5+pos].LimitHi = 0;
-               gGDT[5+pos].Access = 0x89;      // Type
-               gGDT[5+pos].Flags = 0x4;
-               gGDT[5+pos].BaseLow = (Uint)&gTSSs[pos] & 0xFFFF;
-               gGDT[5+pos].BaseMid = (Uint)&gTSSs[pos] >> 16;
-               gGDT[5+pos].BaseHi = (Uint)&gTSSs[pos] >> 24;
+               gGDT[6+pos].LimitLow = sizeof(tTSS);
+               gGDT[6+pos].LimitHi = 0;
+               gGDT[6+pos].Access = 0x89;      // Type
+               gGDT[6+pos].Flags = 0x4;
+               gGDT[6+pos].BaseLow = (Uint)&gTSSs[pos] & 0xFFFF;
+               gGDT[6+pos].BaseMid = (Uint)&gTSSs[pos] >> 16;
+               gGDT[6+pos].BaseHi = (Uint)&gTSSs[pos] >> 24;
        #if USE_MP
        }
        for(pos=0;pos<giNumCPUs;pos++) {
        #endif
-               __asm__ __volatile__ ("ltr %%ax"::"a"(0x28+pos*8));
+               __asm__ __volatile__ ("ltr %%ax"::"a"(0x30+pos*8));
        #if USE_MP
        }
        #endif
@@ -300,6 +317,50 @@ int Proc_Clone(Uint *Err, Uint Flags)
        return newThread->TID;
 }
 
+/**
+ * \fn int Proc_SpawnWorker()
+ * \brief Spawns a new worker thread
+ */
+int Proc_SpawnWorker()
+{
+       tThread *new, *cur;
+       Uint    eip, esp, ebp;
+       
+       cur = Proc_GetCurThread();
+       
+       // Create new thread
+       new = malloc( sizeof(tThread) );
+       if(!new) {
+               Warning("Proc_SpawnWorker - Out of heap space!\n");
+               return -1;
+       }
+       memcpy(new, &gThreadZero, sizeof(tThread));
+       // Set Thread ID
+       new->TID = giNextTID++;
+       // Set kernel stack
+       new->KernelStack = MM_NewWorkerStack();
+
+       // Get ESP and EBP based in the new stack
+       __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
+       __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
+       esp = cur->KernelStack - (new->KernelStack - esp);
+       ebp = new->KernelStack - (cur->KernelStack - ebp);      
+       
+       // Save core machine state
+       new->SavedState.ESP = esp;
+       new->SavedState.EBP = ebp;
+       eip = GetEIP();
+       if(eip == SWITCH_MAGIC) {
+               outb(0x20, 0x20);       // ACK Timer and return as child
+               return 0;
+       }
+       
+       // Set EIP as parent
+       new->SavedState.EIP = eip;
+       
+       return new->TID;
+}
+
 /**
  * \fn Uint Proc_MakeUserStack()
  * \brief Creates a new user stack
index bbdfcfc..9cccec7 100644 (file)
@@ -60,7 +60,7 @@ int Time_Setup()
        outb(0x70, inb(0x70)|0x80);     // Disable NMIs
        
        // Install IRQ Handler
-       //IRQ_AddHandler(8, Time_Interrupt);
+       IRQ_AddHandler(8, Time_Interrupt);
        return 0;
 }
 
@@ -80,7 +80,7 @@ void Time_Interrupt()
        
        //Log("giTimestamp = %lli", giTimestamp);
        
-       Timer_CallTimers();
+       //Timer_CallTimers();
 
        // Make sure the RTC Fires again
        outb(0x70, 0x0C); // Select register C
index ae79ac7..448e87d 100644 (file)
@@ -92,7 +92,7 @@ Uint64        FDD_ReadFS(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);
  int   FDD_Install(char **Arguments);\r
 \r
 // === GLOBALS ===\r
-//MODULE_DEFINE(0, 0x004B, FDD, FDD_Install, NULL, NULL);\r
+MODULE_DEFINE(0, 0x004B, FDD, FDD_Install, NULL, NULL);\r
 static t_floppyDevice  fdd_devices[2];\r
 static volatile int    fdd_inUse = 0;\r
 static volatile int    fdd_irq6 = 0;\r
diff --git a/Kernel/drv/ne2000.c b/Kernel/drv/ne2000.c
deleted file mode 100644 (file)
index a032191..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* Acess2
- * NE2000 Driver
- * 
- * See: ~/Sources/bochs/bochs.../iodev/ne2k.cc
- */
-#define        DEBUG   1
-#include <common.h>
-#include <modules.h>
-#include <fs_devfs.h>
-#include <drv_pci.h>
-
-// === CONSTANTS ===
-#define        MEM_START       0x40
-#define        MEM_END         0xC0
-#define RX_FIRST       (MEM_START)
-#define RX_LAST                (MEM_START+RX_BUF_SIZE-1)
-#define        RX_BUF_SIZE     0x40
-#define TX_FIRST       (MEM_START+RX_BUF_SIZE)
-#define TX_LAST                (MEM_END)
-#define        TX_BUF_SIZE     0x40
-
-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 {
-       CMD = 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 {
-       PSTART = 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
-       
-       Uint8   Buffer[RX_BUF_SIZE];
-       
-       char    Name[2];        // "0"
-       tVFS_Node       Node;
-       Uint8   MacAddr[6];
-} tCard;
-
-// === PROTOTYPES ===
- int   Ne2k_Install(char **Arguments);
-char   *Ne2k_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Ne2k_FindDir(tVFS_Node *Node, char *Name);
-Uint64 Ne2k_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint8  Ne2k_int_GetWritePage(tCard *Card, Uint16 Length);
-void   Ne2k_IRQHandler(int IntNum);
-
-// === GLOBALS ===
-MODULE_DEFINE(0, 0x0032, Ne2k, Ne2k_Install, NULL, NULL);
-tDevFS_Driver  gNe2k_DriverInfo = {
-       NULL, "ne2k",
-       {
-       .NumACLs = 1,
-       .ACLs = &gVFS_ACL_EveryoneRX,
-       .Flags = VFS_FFLAG_DIRECTORY,
-       .ReadDir = Ne2k_ReadDir,
-       .FindDir = Ne2k_FindDir
-       }
-};
-Uint16 gNe2k_BaseAddress;
- int   giNe2k_CardCount = 0;
-tCard  *gpNe2k_Cards = NULL;
-
-// === CODE ===
-/**
- * \fn int Ne2k_Install(char **Options)
- * \brief Installs the NE2000 Driver
- */
-int Ne2k_Install(char **Options)
-{
-        int    i, j, k;
-        int    count, id, base;
-       
-       // --- 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 = 64;
-                       
-                       // Install IRQ Handler
-                       IRQ_AddHandler(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 + CMD, 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 (TCR.LB = 1, Internal Loopback)
-                       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 + CMD, 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, RX_FIRST);   // Set Receive Start
-                       outb( base+BNRY, RX_LAST-1);    // Set Boundary Page
-                       outb( base+PSTOP, RX_LAST);     // 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, 0x0F ); // 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, IOBase=0x%x",
-                               k, gpNe2k_Cards[ k ].IRQ, gpNe2k_Cards[ k ].IOBase);
-                       Log("MAC Address %x:%x:%x:%x:%x:%x",
-                               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.ImplPtr = &gpNe2k_Cards[ k ];
-                       gpNe2k_Cards[ k ].Node.NumACLs = 0;     // Root Only
-                       gpNe2k_Cards[ k ].Node.CTime = now();
-                       gpNe2k_Cards[ k ].Node.Write = Ne2k_Write;
-               }
-       }
-       
-       gNe2k_DriverInfo.RootNode.Size = giNe2k_CardCount;
-       DevFS_AddDevice( &gNe2k_DriverInfo );
-       return 0;
-}
-
-/**
- * \fn char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
- */
-char *Ne2k_ReadDir(tVFS_Node *Node, int Pos)
-{
-       char    ret[2];
-       if(Pos < 0 || Pos >= giNe2k_CardCount)  return NULL;
-       ret[0] = '0'+Pos;
-       ret[1] = '\0';
-       return strdup(ret);
-}
-
-/**
- * \fn tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
- */
-tVFS_Node *Ne2k_FindDir(tVFS_Node *Node, char *Name)
-{
-       if(Name[0] == '\0' || Name[1] != '\0')  return NULL;
-       
-       return &gpNe2k_Cards[ Name[0]-'0' ].Node;
-}
-
-/**
- * \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;
-       Uint16  *buf = Buffer;
-        int    rem = Length;
-       
-       ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
-       
-       // Sanity Check Length
-       if(Length > TX_BUF_SIZE) {
-               LEAVE('i', 0);
-               return 0;
-       }
-       
-       // Make sure that the card is in page 0
-       outb(Card->IOBase + CMD, 0|0x22);       // Page 0, Start, NoDMA
-       
-       // Clear Remote DMA Flag
-       outb(Card->IOBase + ISR, 0x40); // Bit 6
-       
-       // Send Size - Remote Byte Count Register
-       outb(Card->IOBase + TBCR0, Length & 0xFF);
-       outb(Card->IOBase + TBCR1, Length >> 8);
-       
-       // Send Size - Remote Byte Count Register
-       outb(Card->IOBase + RBCR0, Length & 0xFF);
-       outb(Card->IOBase + RBCR1, Length >> 8);
-       
-       // Set up transfer
-       outb(Card->IOBase + RSAR0, 0x00);       // Page Offset
-       outb(Card->IOBase + RSAR1, Ne2k_int_GetWritePage(Card, Length));        // Page Offset
-       // Start
-       //outb(Card->IOBase + CMD, 0|0x18|0x4|0x2);     // Page 0, Transmit Packet, TXP, Start
-       outb(Card->IOBase + CMD, 0|0x10|0x2);   // Page 0, Remote Write, Start
-       
-       // Send Data
-       for(rem = Length; rem; rem -= 2)
-               outw(Card->IOBase + 0x10, *buf++);
-       
-       while( inb(Card->IOBase + ISR) == 0)    // Wait for Remote DMA Complete
-               ;       //Proc_Yield();
-       
-       outb( Card->IOBase + ISR, 0x40 );       // ACK Interrupt
-       
-       // Send Packet
-       outb(Card->IOBase + CMD, 0|0x10|0x4|0x2);
-       
-       // Complete DMA
-       //outb(Card->IOBase + CMD, 0|0x20);
-       
-       LEAVE('i', Length);
-       return Length;
-}
-
-/**
- * \fn Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
- */
-Uint8 Ne2k_int_GetWritePage(tCard *Card, Uint16 Length)
-{
-       Uint8   ret = Card->NextMemPage;
-       
-       Card->NextMemPage += (Length + 0xFF) >> 8;
-       if(Card->NextMemPage >= TX_LAST) {
-               Card->NextMemPage -= TX_BUF_SIZE;
-       }
-       
-       return ret;
-}
-
-/**
- * \fn void Ne2k_IRQHandler(int IntNum)
- */
-void Ne2k_IRQHandler(int IntNum)
-{
-        int    i;
-       for( i = 0; i < giNe2k_CardCount; i++ )
-       {
-               if(gpNe2k_Cards[i].IRQ == IntNum) {
-                       LOG("Clearing interrupts on card %i (0x%x)\n", i, inb( gpNe2k_Cards[i].IOBase + ISR ));
-                       outb( gpNe2k_Cards[i].IOBase + ISR, 0xFF );     // Reset All
-                       return ;
-               }
-       }
-       Warning("[NE2K ] Recieved Unknown IRQ %i", IntNum);
-}
index f340134..16d089d 100644 (file)
@@ -85,19 +85,20 @@ extern void MM_UnmapHWPage(Uint VAddr, Uint Number);
 extern tPAddr  MM_AllocPhys();
 extern void    MM_RefPhys(tPAddr Addr);
 extern void    MM_DerefPhys(tPAddr Addr);
-extern void *memcpy(void *dest, void *src, Uint count);
-extern void *memcpyd(void *dest, void *src, Uint count);
+extern int     memcmp(const void *m1, const void *m2, Uint count);
+extern void *memcpy(void *dest, const void *src, Uint count);
+extern void *memcpyd(void *dest, const void *src, Uint count);
 extern void *memset(void *dest, int val, Uint count);
 extern void *memsetd(void *dest, Uint val, Uint count);
 // --- Strings ---
-extern Uint    strlen(char *Str);
-extern char    *strcpy(char *__dest, char *__src);
-extern int     strcmp(char *__dest, char *__src);
-extern int     strncmp(char *Str1, char *Str2, size_t num);
-extern int     strucmp(char *Str1, char *Str2);
-extern char    *strdup(char *__str);
-extern int     strpos(char *Str, char Ch);
-extern int     strpos8(char *str, Uint32 search);
+extern Uint    strlen(const char *Str);
+extern char    *strcpy(char *__dest, const char *__src);
+extern int     strcmp(const char *__str1, const char *__str2);
+extern int     strncmp(const char *Str1, const char *Str2, size_t num);
+extern int     strucmp(const char *Str1, const char *Str2);
+extern char    *strdup(const char *__str);
+extern int     strpos(const char *Str, char Ch);
+extern int     strpos8(const char *str, Uint32 search);
 extern void    itoa(char *buf, Uint num, int base, int minLength, char pad);
 extern int     ReadUTF8(Uint8 *str, Uint32 *Val);
 extern int     WriteUTF8(Uint8 *str, Uint32 Val);
@@ -117,6 +118,7 @@ extern int  Time_CreateTimer(int Delta, void *Callback, void *Argument);
 extern void    Time_RemoveTimer(int ID);
 extern void    Time_Delay(int Delay);
 // --- Threads ---
+extern  int    Proc_SpawnWorker();
 extern  int    Proc_Spawn(char *Path);
 extern void    Threads_Exit();
 extern void    Threads_Yield();
index 68d48a6..d3fff54 100644 (file)
@@ -70,7 +70,7 @@ int tolower(int c)
  * \fn int strucmp(char *Str1, char *Str2)
  * \brief Compare \a Str1 and \a Str2 case-insensitively
  */
-int strucmp(char *Str1, char *Str2)
+int strucmp(const char *Str1, const char *Str2)
 {
        while(*Str1 && tolower(*Str1) == tolower(*Str2))
                Str1++, Str2++;
@@ -81,7 +81,7 @@ int strucmp(char *Str1, char *Str2)
  * \fn int strpos(char *Str, char Ch)
  * \brief Search a string for an ascii character
  */
-int strpos(char *Str, char Ch)
+int strpos(const char *Str, char Ch)
 {
         int    pos;
        for(pos=0;Str[pos];pos++)
@@ -104,7 +104,7 @@ int ByteSum(void *Ptr, int Size)
  * \fn Uint strlen(char *__str)
  * \brief Get the length of string
  */
-Uint strlen(char *__str)
+Uint strlen(const char *__str)
 {
        Uint    ret = 0;
        while(*__str++) ret++;
@@ -115,7 +115,7 @@ Uint strlen(char *__str)
  * \fn char *strcpy(char *__str1, char *__str2)
  * \brief Copy a string to a new location
  */
-char *strcpy(char *__str1, char *__str2)
+char *strcpy(char *__str1, const char *__str2)
 {
        while(*__str2)
                *__str1++ = *__str2++;
@@ -128,7 +128,7 @@ char *strcpy(char *__str1, char *__str2)
  * \brief Compare two strings return the difference between
  *        the first non-matching characters.
  */
-int strcmp(char *str1, char *str2)
+int strcmp(const char *str1, const char *str2)
 {
        while(*str1 && *str1 == *str2)
                str1++, str2++;
@@ -139,7 +139,7 @@ int strcmp(char *str1, char *str2)
  * \fn int strncmp(char *Str1, char *Str2, size_t num)
  * \brief Compare strings \a Str1 and \a Str2 to a maximum of \a num characters
  */
-int strncmp(char *Str1, char *Str2, size_t num)
+int strncmp(const char *Str1, const char *Str2, size_t num)
 {
        if(num == 0)    return 0;       // TODO: Check what should officially happen here
        while(--num && *Str1 && *Str1 == *Str2)
@@ -151,7 +151,7 @@ int strncmp(char *Str1, char *Str2, size_t num)
  * \fn char *strdup(char *str)
  * \brief Duplicates a string
  */
-char *strdup(char *str)
+char *strdup(const char *str)
 {
        char    *ret;
        ret = malloc(strlen(str)+1);
@@ -174,7 +174,7 @@ int DivUp(int num, int dem)
  * \fn int strpos8(char *str, Uint32 search)
  * \brief Search a string for a UTF-8 character
  */
-int strpos8(char *str, Uint32 Search)
+int strpos8(const char *str, Uint32 Search)
 {
         int    pos;
        Uint32  val = 0;
index 9b160d9..4dc92c8 100644 (file)
@@ -232,10 +232,10 @@ void System_ExecuteScript()
                }
                // - Load Module
                else if(strncmp("module ", fData+i, 6) == 0) {
+                       //char  *tmp;
                        i += 7;
                        i += System_Int_GetString(fData+i, &sArg1);
                        if(!sArg1)      goto read2eol;
-                       //Log("[CFG ] Load Module '%s'\n", sArg1);
                        Module_LoadFile(sArg1, "");     //!\todo Use the rest of the line as the argument string
                }
                // - Load Module
index dd7cfcd..3be9789 100644 (file)
@@ -464,7 +464,7 @@ void Threads_Sleep()
        tThread *cur = Proc_GetCurThread();
        tThread *thread;
        
-       //Log("Proc_Sleep: %i going to sleep", cur->TID);
+       Log("Proc_Sleep: %i going to sleep", cur->TID);
        
        // Acquire Spinlock
        LOCK( &giThreadListLock );
@@ -472,7 +472,8 @@ void Threads_Sleep()
        // Get thread before current thread
        thread = Threads_int_GetPrev( &gActiveThreads, cur );
        if(!thread) {
-               Warning("Proc_Sleep - Current thread is not on the active queue");
+               Warning("Threads_Sleep - Current thread is not on the active queue");
+               Threads_Dump();
                return;
        }
        
@@ -502,11 +503,11 @@ void Threads_Sleep()
        // Release Spinlock
        RELEASE( &giThreadListLock );
        
-       HALT();
+       while(cur->Status != THREAD_STAT_ACTIVE)        HALT();
 }
 
 
-/**c0108919:
+/**
  * \fn void Threads_Wake( tThread *Thread )
  * \brief Wakes a sleeping/waiting thread up
  */
@@ -630,18 +631,23 @@ int Threads_GetGID()
 void Threads_Dump()
 {
        tThread *thread;
+       tThread *cur = Proc_GetCurThread();
        
        Log("Active Threads:");
        for(thread=gActiveThreads;thread;thread=thread->Next)
        {
-               Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName);
+               Log("%c%i (%i) - %s",
+                       (thread==cur?'*':' '),
+                       thread->TID, thread->TGID, thread->ThreadName);
                Log("  %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
                Log("  KStack 0x%x", thread->KernelStack);
        }
        Log("Sleeping Threads:");
        for(thread=gSleepingThreads;thread;thread=thread->Next)
        {
-               Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName);
+               Log("%c%i (%i) - %s",
+                       (thread==cur?'*':' '),
+                       thread->TID, thread->TGID, thread->ThreadName);
                Log("  %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum);
                Log("  KStack 0x%x", thread->KernelStack);
        }
index fe0f25d..50be904 100644 (file)
@@ -13,6 +13,8 @@
 #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
@@ -42,6 +44,9 @@ tVFS_Node     *Ext2_FindDir(tVFS_Node *Node, char *FileName);
 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
@@ -478,7 +483,6 @@ int Ext2_MkNod(tVFS_Node *Parent, char *Name, Uint Flags)
 \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
@@ -630,3 +634,105 @@ Uint64 Ext2_int_GetBlockAddr(tExt2_Disk *Disk, Uint32 *Blocks, int BlockNum)
        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
index 57adb85..f6f0061 100644 (file)
@@ -14,8 +14,9 @@ RMDIR = rm -rf
 ARCH = i386
 ARCHDIR = x86
 
-DRIVERS = ata_x86 ne2000
-# fdd
+FILESYSTEMS = fat ext2
+DRIVERS = ata_x86 fdd
+MODULES = ne2000
 
 DISTROOT = /mnt/AcessHDD/Acess2
 ACESSDIR = /home/hodgeja/Projects/Acess2

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