12 int Modules_LoadBuiltins();
13 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
14 int Module_LoadFile(char *Path, char *ArgString);
15 int Module_int_ResolveDeps(tModule *Info);
16 int Module_IsLoaded(char *Name);
20 extern int UDI_LoadDriver(void *Base);
22 extern void StartupPrint(char *Str);
23 extern tModule gKernelModules[];
24 extern void gKernelModulesEnd;
27 int giNumBuiltinModules = 0;
28 int giModuleSpinlock = 0;
29 tModule *gLoadedModules = NULL;
30 tModuleLoader *gModule_Loaders = NULL;
33 int Modules_LoadBuiltins()
42 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
43 giNumBuiltinModules /= sizeof(tModule);
45 // Allocate loaded array
46 baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
48 // Pass 1 - Check for dependencies
49 for( i = 0; i < giNumBuiltinModules; i++ )
51 deps = gKernelModules[i].Dependencies;
54 for( j = 0; deps[j]; j++ )
56 for( k = 0; k < giNumBuiltinModules; k++ ) {
57 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
60 if(k == giNumBuiltinModules) {
62 "[MOD ] Dependency '%s' for module '%s' was not compiled in",
63 deps[j], gKernelModules[i].Name
66 baIsLoaded[i] = -1; // Don't Load
74 // Pass 2 - Intialise modules in order
77 for( i = 0; i < giNumBuiltinModules; i++ )
79 if( baIsLoaded[i] ) continue; // Ignore already loaded modules
81 deps = gKernelModules[i].Dependencies;
85 for( j = 0; deps[j]; j++ )
87 for( k = 0; k < giNumBuiltinModules; k++ ) {
88 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
91 // `k` is assumed to be less than `giNumBuiltinModules`
92 // We checked this in pass 1
94 // If a dependency failed, skip and mark as failed
95 if( baIsLoaded[k] == -1 ) {
100 // If a dependency is not intialised, skip this module
101 // and come back later
102 if( !baIsLoaded[k] ) break;
104 // Check for breakouts
105 if( deps[j] ) continue;
108 // All Dependencies OK? Initialise
109 StartupPrint(gKernelModules[i].Name);
110 Log("[MOD ] Initialising %p '%s' v%i.%i...",
112 gKernelModules[i].Name,
113 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
116 ret = gKernelModules[i].Init(NULL);
117 if( ret != MODULE_ERR_OK ) {
118 Log("[MOD ] Loading Failed, all modules that depend on this will also fail");
121 case MODULE_ERR_MISC:
122 Log("[MOD ] Reason: Miscelanious");
124 case MODULE_ERR_NOTNEEDED:
125 Log("[MOD ] Reason: Module not needed (probably hardware not found)");
127 case MODULE_ERR_MALLOC:
128 Log("[MOD ] Reason: Error in malloc/realloc/calloc, probably not good");
131 Log("[MOD ] Reason - Unknown code %i", ret);
149 * \brief Registers a tModuleLoader with the kernel
150 * \param Loader Pointer to loader structure (must be persistent)
152 int Module_RegisterLoader(tModuleLoader *Loader)
154 if(!Loader) return 1;
156 Loader->Next = gModule_Loaders;
157 gModule_Loaders = Loader;
163 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
164 * \brief Load a module from a memory location
166 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
168 char path[VFS_MEMPATH_SIZE];
170 VFS_GetMemPath(path, Buffer, Length);
172 return Module_LoadFile( path, ArgString );
176 * \fn int Module_LoadFile(char *Path, char *ArgString)
177 * \brief Load a module from a file
179 int Module_LoadFile(char *Path, char *ArgString)
185 base = Binary_LoadKernel(Path);
189 Warning("Module_LoadFile: Unable to load '%s'", Path);
193 // Check for Acess Driver
194 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
197 for( tmp = gModule_Loaders; tmp; tmp = tmp->Next)
199 if( tmp->Detector(base) == 0 ) continue;
201 return tmp->Loader(base);
205 // Check for EDI Driver
206 if( Binary_FindSymbol(base, "driver_init", NULL ) != 0 )
208 return Module_InitEDI( base ); // And intialise
212 // Unknown module type?, return error
215 Warning("Module_LoadFile: Module has neither a Module Info struct, nor an EDI entrypoint");
217 Warning("Module_LoadFile: Module does not have a Module Info struct");
222 // Check magic number
223 if(info->Magic != MODULE_MAGIC)
225 Warning("Module_LoadFile: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
229 // Check Architecture
230 if(info->Arch != MODULE_ARCH_ID)
232 Warning("Module_LoadFile: Module is for a different architecture");
236 // Resolve Dependencies
237 if( !Module_int_ResolveDeps(info) ) {
242 Log("Initialising %p '%s' v%i.%i...",
245 info->Version>>8, info->Version & 0xFF
249 //if( info->Init( ArgString ) != 0 )
250 if( info->Init( NULL ) == 0 )
257 LOCK( &giModuleSpinlock );
258 info->Next = gLoadedModules;
259 gLoadedModules = info;
260 RELEASE( &giModuleSpinlock );
266 * \fn int Module_int_ResolveDeps(tModule *Info)
267 * \brief Resolves the dependencies
269 * \note Currently does not resolve the dependencies, just checks them
271 int Module_int_ResolveDeps(tModule *Info)
273 char **names = Info->Dependencies;
275 // Walk dependencies array
276 for( ; *names; names++ )
278 // Check if the module is loaded
279 if( !Module_IsLoaded(*names) ) {
280 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
288 * \fn int Module_IsLoaded(char *Name)
289 * \brief Checks if a module is loaded
290 * \param Name Name of module to find
292 int Module_IsLoaded(char *Name)
294 tModule *mod = gLoadedModules;
297 for( ; mod; mod = mod->Next )
299 // If found, return true
300 if(strcmp(mod->Name, Name) == 0)
303 // not found - return false