Restructured Modules_LoadBuiltins to load modules in the order they are linked in.
authorJohn Hodge <[email protected]>
Sun, 14 Mar 2010 03:32:13 +0000 (11:32 +0800)
committerJohn Hodge <[email protected]>
Sun, 14 Mar 2010 03:32:13 +0000 (11:32 +0800)
- Also moved vterm.o to be linked earlier
- Removed a newline from a Log() in ne2000.c

Kernel/Makefile
Kernel/Makefile.BuildNum
Kernel/modules.c
Modules/Network/NE2000/ne2000.c

index 619d3ea..9825a3d 100644 (file)
@@ -28,9 +28,6 @@ endif
 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 += $(addprefix vfs/fs/, $(addsuffix .o,$(FILESYSTEMS)))
-# These are first to make vterm be the first driver initialised (apart
-# its dependencies), allowing logging to exist throughout the loading
-# process.
 OBJ += drv/vterm.o drv/proc.o drv/fifo.o drv/dma.o drv/iocache.o drv/pci.o drv/kb.o drv/vga.o
 OBJ += binary.o bin/elf.o bin/pe.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
index d15c45a..a4aa121 100644 (file)
@@ -1 +1 @@
-BUILD_NUM = 1518
+BUILD_NUM = 1525
index 39c9966..389663a 100644 (file)
@@ -2,6 +2,7 @@
  * Acess2
  * - Module Loader
  */
+#define DEBUG  0
 #include <acess.h>
 #include <modules.h>
 
@@ -28,119 +29,123 @@ extern void       gKernelModulesEnd;
  int   giModuleSpinlock = 0;
 tModule        *gLoadedModules = NULL;
 tModuleLoader  *gModule_Loaders = NULL;
+tModule        *gLoadingModules = NULL;
 
 // === CODE ===
-int Modules_LoadBuiltins()
+int Module_int_Initialise(tModule *Module)
 {
-        int    i, j, k;
+        int    i, j;
         int    ret;
-        int    numToInit = 0;
-       Uint8   *baIsLoaded;
        char    **deps;
+       tModule *mod;
        
-       // Count modules
-       giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
-       giNumBuiltinModules /= sizeof(tModule);
+       ENTER("pModule", Module);
        
-       // Allocate loaded array
-       baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
+       deps = Module->Dependencies;
        
-       // Pass 1 - Check for dependencies
-       for( i = 0; i < giNumBuiltinModules; i++ )
+       // Check if the module has been loaded
+       for( mod = gLoadedModules; mod; mod = mod->Next )
        {
-               deps = gKernelModules[i].Dependencies;
-               if(deps)
-               {
-                       for( j = 0; deps[j]; j++ )
-                       {
-                               for( k = 0; k < giNumBuiltinModules; k++ ) {
-                                       if(strcmp(deps[j], gKernelModules[k].Name) == 0)
-                                               break;
-                               }
-                               if(k == giNumBuiltinModules) {
-                                       Warning(
-                                               "[MOD  ] Dependency '%s' for module '%s' was not compiled in",
-                                               deps[j], gKernelModules[i].Name
-                                               );
-                                       
-                                       baIsLoaded[i] = -1;     // Don't Load
-                                       break;
-                               }
-                       }
-               }
-               numToInit ++;
+               if(mod == Module)       LEAVE_RET('i', 0);
        }
        
-       // Pass 2 - Intialise modules in order
-       while(numToInit)
+       // Add to the "loading" (prevents circular deps)
+       Module->Next = gLoadingModules;
+       gLoadingModules = Module;
+       
+       // Scan dependency list
+       for( j = 0; deps && deps[j]; j++ )
        {
-               for( i = 0; i < giNumBuiltinModules; i++ )
+               // Check if the module is already loaded
+               for( mod = gLoadedModules; mod; mod = mod->Next )
                {
-                       if( baIsLoaded[i] )     continue;       // Ignore already loaded modules
+                       if(strcmp(deps[j], mod->Name) == 0)
+                               break;
+               }
+               if( mod )       continue;       // Dependency is loaded, check the rest
                
-                       deps = gKernelModules[i].Dependencies;
-                       
-                       if( deps )
-                       {
-                               for( j = 0; deps[j]; j++ )
-                               {
-                                       for( k = 0; k < giNumBuiltinModules; k++ ) {
-                                               if(strcmp(deps[j], gKernelModules[k].Name) == 0)
-                                                       break;
-                                       }
-                                       // `k` is assumed to be less than `giNumBuiltinModules`
-                                       // We checked this in pass 1
-                                       
-                                       // If a dependency failed, skip and mark as failed
-                                       if( baIsLoaded[k] == -1 ) {
-                                               baIsLoaded[i] = -1;
-                                               numToInit --;
-                                               break;
-                                       }
-                                       // If a dependency is not intialised, skip this module
-                                       // and come back later
-                                       if( !baIsLoaded[k] )    break;
-                               }
-                               // Check for breakouts
-                               if( deps[j] )   continue;
-                       }
-                       
-                       // All Dependencies OK? Initialise
-                       StartupPrint(gKernelModules[i].Name);
-                       Log("[MOD  ] Initialising %p '%s' v%i.%i...",
-                               &gKernelModules[i],
-                               gKernelModules[i].Name,
-                               gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
-                               );
-                       
-                       ret = gKernelModules[i].Init(NULL);
-                       if( ret != MODULE_ERR_OK ) {
-                               Log("[MOD  ] Loading Failed, all modules that depend on this will also fail");
-                               switch(ret)
-                               {
-                               case MODULE_ERR_MISC:
-                                       Log("[MOD  ] Reason: Miscelanious");
-                                       break;
-                               case MODULE_ERR_NOTNEEDED:
-                                       Log("[MOD  ] Reason: Module not needed (probably hardware not found)");
-                                       break;
-                               case MODULE_ERR_MALLOC:
-                                       Log("[MOD  ] Reason: Error in malloc/realloc/calloc, probably not good");
-                                       break;
-                               default:
-                                       Log("[MOD  ] Reason - Unknown code %i", ret);
-                                       break;
-                               }
-                               baIsLoaded[i] = -1;
-                       }
-                       // Mark as loaded
-                       else
-                               baIsLoaded[i] = 1;
-                       numToInit --;
+               // Ok, check if it's loading
+               for( mod = gLoadingModules->Next; mod; mod = mod->Next )
+               {
+                       if(strcmp(deps[j], mod->Name) == 0)
+                               break;
+               }
+               if( mod ) {
+                       Warning("[MOD  ] Circular dependency detected");
+                       LEAVE_RET('i', -1);
+               }
+               
+               // So, if it's not loaded, we better load it then
+               for( i = 0; i < giNumBuiltinModules; i ++ )
+               {
+                       if( strcmp(deps[j], gKernelModules[i].Name) == 0 )
+                               break;
+               }
+               if( i == giNumBuiltinModules ) {
+                       Warning("[MOD  ] Dependency '%s' for module '%s' failed");
+                       return -1;
                }
+               
+               // Dependency is not loaded, so load it
+               ret = Module_int_Initialise( &gKernelModules[i] );
+               if( ret )
+               {
+                       // The only "ok" error is NOTNEEDED
+                       if(ret != MODULE_ERR_NOTNEEDED)
+                               LEAVE_RET('i', -1);
+               }
+       }
+       
+       // All Dependencies OK? Initialise
+       StartupPrint(Module->Name);
+       Log("[MOD  ] Initialising %p '%s' v%i.%i...",
+               Module, Module->Name,
+               Module->Version >> 8, Module->Version & 0xFF
+               );
+       
+       ret = Module->Init(NULL);
+       if( ret != MODULE_ERR_OK ) {
+               Log("[MOD  ] Loading Failed, all modules that depend on this will also fail");
+               switch(ret)
+               {
+               case MODULE_ERR_MISC:
+                       Log("[MOD  ] Reason: Miscelanious");
+                       break;
+               case MODULE_ERR_NOTNEEDED:
+                       Log("[MOD  ] Reason: Module not needed (probably hardware not found)");
+                       break;
+               case MODULE_ERR_MALLOC:
+                       Log("[MOD  ] Reason: Error in malloc/realloc/calloc, probably not good");
+                       break;
+               default:
+                       Log("[MOD  ] Reason - Unknown code %i", ret);
+                       break;
+               }
+               LEAVE_RET('i', ret);
        }
        
-       free(baIsLoaded);
+       // Remove from loading list
+       gLoadingModules = gLoadingModules->Next;
+       
+       // Add to loaded list
+       Module->Next = gLoadedModules;
+       gLoadedModules = Module;
+       
+       LEAVE_RET('i', 0);
+}
+
+int Modules_LoadBuiltins()
+{
+        int    i;
+       
+       // Count modules
+       giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
+       giNumBuiltinModules /= sizeof(tModule);
+       
+       for( i = 0; i < giNumBuiltinModules; i++ )
+       {
+               Module_int_Initialise( &gKernelModules[i] );
+       }
        
        return 0;
 }
index 700c35e..40d9b82 100644 (file)
@@ -128,7 +128,7 @@ int Ne2k_Install(char **Options)
        }
        
        if( giNe2k_CardCount == 0 ) {
-               Log("[Ne2k ] No cards detected\n");
+               Warning("[Ne2k ] No cards detected");
                return MODULE_ERR_NOTNEEDED;
        }
        

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