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 tSpinlock glModuleSpinlock;
30 tModule *gLoadedModules = NULL;
31 tModuleLoader *gModule_Loaders = NULL;
32 tModule *gLoadingModules = NULL;
36 * \brief Initialises a module
37 * \param Module Pointer to the module header
38 * \return Zero on success, eModuleErrors or -1 on error
39 * \retval -1 Returned if a dependency fails, or a circular dependency
41 * \retval 0 Returned on success
42 * \retval >0 Error code form the module's initialisation function
44 int Module_int_Initialise(tModule *Module)
51 ENTER("pModule", Module);
53 deps = Module->Dependencies;
55 // Check if the module has been loaded
56 for( mod = gLoadedModules; mod; mod = mod->Next )
58 if(mod == Module) LEAVE_RET('i', 0);
61 // Add to the "loading" (prevents circular deps)
62 Module->Next = gLoadingModules;
63 gLoadingModules = Module;
65 // Scan dependency list
66 for( j = 0; deps && deps[j]; j++ )
68 // Check if the module is already loaded
69 for( mod = gLoadedModules; mod; mod = mod->Next )
71 if(strcmp(deps[j], mod->Name) == 0)
74 if( mod ) continue; // Dependency is loaded, check the rest
76 // Ok, check if it's loading
77 for( mod = gLoadingModules->Next; mod; mod = mod->Next )
79 if(strcmp(deps[j], mod->Name) == 0)
83 Warning("[MOD ] Circular dependency detected");
87 // So, if it's not loaded, we better load it then
88 for( i = 0; i < giNumBuiltinModules; i ++ )
90 if( strcmp(deps[j], gKernelModules[i].Name) == 0 )
93 if( i == giNumBuiltinModules ) {
94 Warning("[MOD ] Dependency '%s' for module '%s' failed");
98 // Dependency is not loaded, so load it
99 ret = Module_int_Initialise( &gKernelModules[i] );
102 // The only "ok" error is NOTNEEDED
103 if(ret != MODULE_ERR_NOTNEEDED)
108 // All Dependencies OK? Initialise
109 StartupPrint(Module->Name);
110 Log("[MOD ] Initialising %p '%s' v%i.%i...",
111 Module, Module->Name,
112 Module->Version >> 8, Module->Version & 0xFF
115 ret = Module->Init(NULL);
116 if( ret != MODULE_ERR_OK ) {
119 case MODULE_ERR_MISC:
120 Warning("[MOD ] Unable to load, reason: Miscelanious");
122 case MODULE_ERR_NOTNEEDED:
123 Warning("[MOD ] Unable to load, reason: Module not needed (probably hardware not found)");
125 case MODULE_ERR_MALLOC:
126 Warning("[MOD ] Unable to load, reason: Error in malloc/realloc/calloc, probably not good");
129 Warning("[MOD ] Unable to load reason - Unknown code %i", ret);
136 // Remove from loading list
137 gLoadingModules = gLoadingModules->Next;
139 // Add to loaded list
140 LOCK( &glModuleSpinlock );
141 Module->Next = gLoadedModules;
142 gLoadedModules = Module;
143 RELEASE( &glModuleSpinlock );
149 * \brief Initialises builtin modules
151 int Modules_LoadBuiltins()
156 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
157 giNumBuiltinModules /= sizeof(tModule);
159 for( i = 0; i < giNumBuiltinModules; i++ )
161 Module_int_Initialise( &gKernelModules[i] );
168 * \brief Registers a tModuleLoader with the kernel
169 * \param Loader Pointer to loader structure (must be persistent)
171 int Module_RegisterLoader(tModuleLoader *Loader)
173 if(!Loader) return 1;
175 Loader->Next = gModule_Loaders;
176 gModule_Loaders = Loader;
182 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
183 * \brief Load a module from a memory location
185 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
187 char path[VFS_MEMPATH_SIZE];
189 VFS_GetMemPath(path, Buffer, Length);
191 return Module_LoadFile( path, ArgString );
195 * \fn int Module_LoadFile(char *Path, char *ArgString)
196 * \brief Load a module from a file
198 int Module_LoadFile(char *Path, char *ArgString)
204 base = Binary_LoadKernel(Path);
208 Warning("Module_LoadFile: Unable to load '%s'", Path);
212 // Check for Acess Driver
213 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
216 for( tmp = gModule_Loaders; tmp; tmp = tmp->Next)
218 if( tmp->Detector(base) == 0 ) continue;
220 return tmp->Loader(base);
224 // Check for EDI Driver
225 if( Binary_FindSymbol(base, "driver_init", NULL ) != 0 )
227 return Module_InitEDI( base ); // And intialise
231 // Unknown module type?, return error
234 Warning("Module_LoadFile: Module has neither a Module Info struct, nor an EDI entrypoint");
236 Warning("Module_LoadFile: Module does not have a Module Info struct");
241 // Check magic number
242 if(info->Magic != MODULE_MAGIC)
244 Warning("Module_LoadFile: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
248 // Check Architecture
249 if(info->Arch != MODULE_ARCH_ID)
251 Warning("Module_LoadFile: Module is for a different architecture");
256 if( Module_int_Initialise( info ) )
262 // Resolve Dependencies
263 if( !Module_int_ResolveDeps(info) ) {
268 Log("Initialising %p '%s' v%i.%i...",
271 info->Version>>8, info->Version & 0xFF
275 //if( info->Init( ArgString ) != 0 )
276 if( info->Init( NULL ) == 0 )
283 LOCK( &glModuleSpinlock );
284 info->Next = gLoadedModules;
285 gLoadedModules = info;
286 RELEASE( &glModuleSpinlock );
293 * \fn int Module_int_ResolveDeps(tModule *Info)
294 * \brief Resolves the dependencies
296 * \note Currently does not resolve the dependencies, just checks them
298 int Module_int_ResolveDeps(tModule *Info)
300 char **names = Info->Dependencies;
302 // Walk dependencies array
303 for( ; *names; names++ )
305 // Check if the module is loaded
306 if( !Module_IsLoaded(*names) ) {
307 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
315 * \fn int Module_IsLoaded(char *Name)
316 * \brief Checks if a module is loaded
317 * \param Name Name of module to find
319 int Module_IsLoaded(char *Name)
321 tModule *mod = gLoadedModules;
324 for( ; mod; mod = mod->Next )
326 // If found, return true
327 if(strcmp(mod->Name, Name) == 0)
330 // not found - return false