From: John Hodge Date: Sun, 14 Mar 2010 03:32:13 +0000 (+0800) Subject: Restructured Modules_LoadBuiltins to load modules in the order they are linked in. X-Git-Tag: rel0.06~282 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=701555cd9e3aa5131572043867e15387db3cddef;p=tpg%2Facess2.git Restructured Modules_LoadBuiltins to load modules in the order they are linked in. - Also moved vterm.o to be linked earlier - Removed a newline from a Log() in ne2000.c --- diff --git a/Kernel/Makefile b/Kernel/Makefile index 619d3ea0..9825a3d5 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -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 diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index d15c45a5..a4aa1218 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 1518 +BUILD_NUM = 1525 diff --git a/Kernel/modules.c b/Kernel/modules.c index 39c99661..389663af 100644 --- a/Kernel/modules.c +++ b/Kernel/modules.c @@ -2,6 +2,7 @@ * Acess2 * - Module Loader */ +#define DEBUG 0 #include #include @@ -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; } diff --git a/Modules/Network/NE2000/ne2000.c b/Modules/Network/NE2000/ne2000.c index 700c35e7..40d9b823 100644 --- a/Modules/Network/NE2000/ne2000.c +++ b/Modules/Network/NE2000/ne2000.c @@ -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; }