13 int Modules_LoadBuiltins();
14 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
15 int Module_LoadFile(char *Path, char *ArgString);
16 int Module_int_ResolveDeps(tModule *Info);
17 int Module_IsLoaded(char *Name);
21 extern int UDI_LoadDriver(void *Base);
23 extern void StartupPrint(char *Str);
24 extern tModule gKernelModules[];
25 extern void gKernelModulesEnd;
28 int giNumBuiltinModules = 0;
29 int giModuleSpinlock = 0;
30 tModule *gLoadedModules = NULL;
31 tModuleLoader *gModule_Loaders = NULL;
32 tModule *gLoadingModules = NULL;
35 int Module_int_Initialise(tModule *Module)
42 ENTER("pModule", Module);
44 deps = Module->Dependencies;
46 // Check if the module has been loaded
47 for( mod = gLoadedModules; mod; mod = mod->Next )
49 if(mod == Module) LEAVE_RET('i', 0);
52 // Add to the "loading" (prevents circular deps)
53 Module->Next = gLoadingModules;
54 gLoadingModules = Module;
56 // Scan dependency list
57 for( j = 0; deps && deps[j]; j++ )
59 // Check if the module is already loaded
60 for( mod = gLoadedModules; mod; mod = mod->Next )
62 if(strcmp(deps[j], mod->Name) == 0)
65 if( mod ) continue; // Dependency is loaded, check the rest
67 // Ok, check if it's loading
68 for( mod = gLoadingModules->Next; mod; mod = mod->Next )
70 if(strcmp(deps[j], mod->Name) == 0)
74 Warning("[MOD ] Circular dependency detected");
78 // So, if it's not loaded, we better load it then
79 for( i = 0; i < giNumBuiltinModules; i ++ )
81 if( strcmp(deps[j], gKernelModules[i].Name) == 0 )
84 if( i == giNumBuiltinModules ) {
85 Warning("[MOD ] Dependency '%s' for module '%s' failed");
89 // Dependency is not loaded, so load it
90 ret = Module_int_Initialise( &gKernelModules[i] );
93 // The only "ok" error is NOTNEEDED
94 if(ret != MODULE_ERR_NOTNEEDED)
99 // All Dependencies OK? Initialise
100 StartupPrint(Module->Name);
101 Log("[MOD ] Initialising %p '%s' v%i.%i...",
102 Module, Module->Name,
103 Module->Version >> 8, Module->Version & 0xFF
106 ret = Module->Init(NULL);
107 if( ret != MODULE_ERR_OK ) {
108 Log("[MOD ] Loading Failed, all modules that depend on this will also fail");
111 case MODULE_ERR_MISC:
112 Log("[MOD ] Reason: Miscelanious");
114 case MODULE_ERR_NOTNEEDED:
115 Log("[MOD ] Reason: Module not needed (probably hardware not found)");
117 case MODULE_ERR_MALLOC:
118 Log("[MOD ] Reason: Error in malloc/realloc/calloc, probably not good");
121 Log("[MOD ] Reason - Unknown code %i", ret);
127 // Remove from loading list
128 gLoadingModules = gLoadingModules->Next;
130 // Add to loaded list
131 Module->Next = gLoadedModules;
132 gLoadedModules = Module;
137 int Modules_LoadBuiltins()
142 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
143 giNumBuiltinModules /= sizeof(tModule);
145 for( i = 0; i < giNumBuiltinModules; i++ )
147 Module_int_Initialise( &gKernelModules[i] );
154 * \brief Registers a tModuleLoader with the kernel
155 * \param Loader Pointer to loader structure (must be persistent)
157 int Module_RegisterLoader(tModuleLoader *Loader)
159 if(!Loader) return 1;
161 Loader->Next = gModule_Loaders;
162 gModule_Loaders = Loader;
168 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
169 * \brief Load a module from a memory location
171 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
173 char path[VFS_MEMPATH_SIZE];
175 VFS_GetMemPath(path, Buffer, Length);
177 return Module_LoadFile( path, ArgString );
181 * \fn int Module_LoadFile(char *Path, char *ArgString)
182 * \brief Load a module from a file
184 int Module_LoadFile(char *Path, char *ArgString)
190 base = Binary_LoadKernel(Path);
194 Warning("Module_LoadFile: Unable to load '%s'", Path);
198 // Check for Acess Driver
199 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
202 for( tmp = gModule_Loaders; tmp; tmp = tmp->Next)
204 if( tmp->Detector(base) == 0 ) continue;
206 return tmp->Loader(base);
210 // Check for EDI Driver
211 if( Binary_FindSymbol(base, "driver_init", NULL ) != 0 )
213 return Module_InitEDI( base ); // And intialise
217 // Unknown module type?, return error
220 Warning("Module_LoadFile: Module has neither a Module Info struct, nor an EDI entrypoint");
222 Warning("Module_LoadFile: Module does not have a Module Info struct");
227 // Check magic number
228 if(info->Magic != MODULE_MAGIC)
230 Warning("Module_LoadFile: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
234 // Check Architecture
235 if(info->Arch != MODULE_ARCH_ID)
237 Warning("Module_LoadFile: Module is for a different architecture");
241 // Resolve Dependencies
242 if( !Module_int_ResolveDeps(info) ) {
247 Log("Initialising %p '%s' v%i.%i...",
250 info->Version>>8, info->Version & 0xFF
254 //if( info->Init( ArgString ) != 0 )
255 if( info->Init( NULL ) == 0 )
262 LOCK( &giModuleSpinlock );
263 info->Next = gLoadedModules;
264 gLoadedModules = info;
265 RELEASE( &giModuleSpinlock );
271 * \fn int Module_int_ResolveDeps(tModule *Info)
272 * \brief Resolves the dependencies
274 * \note Currently does not resolve the dependencies, just checks them
276 int Module_int_ResolveDeps(tModule *Info)
278 char **names = Info->Dependencies;
280 // Walk dependencies array
281 for( ; *names; names++ )
283 // Check if the module is loaded
284 if( !Module_IsLoaded(*names) ) {
285 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
293 * \fn int Module_IsLoaded(char *Name)
294 * \brief Checks if a module is loaded
295 * \param Name Name of module to find
297 int Module_IsLoaded(char *Name)
299 tModule *mod = gLoadedModules;
302 for( ; mod; mod = mod->Next )
304 // If found, return true
305 if(strcmp(mod->Name, Name) == 0)
308 // not found - return false