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()
40 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
41 giNumBuiltinModules /= sizeof(tModule);
43 baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
45 // Pass 1 - Are the dependencies compiled in?
46 for( i = 0; i < giNumBuiltinModules; i++ )
48 deps = gKernelModules[i].Dependencies;
51 for( j = 0; deps[j]; j++ )
53 for( k = 0; k < giNumBuiltinModules; k++ ) {
54 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
57 if(k == giNumBuiltinModules) {
58 Warning("Unable to find dependency '%s' for '%s' in kernel",
59 deps[j], gKernelModules[i].Name);
61 baIsLoaded[i] = -1; // Don't Load
72 for( i = 0; i < giNumBuiltinModules; i++ )
74 if( baIsLoaded[i] ) continue; // Ignore already loaded modules
76 deps = gKernelModules[i].Dependencies;
80 for( j = 0; deps[j]; j++ )
82 for( k = 0; k < giNumBuiltinModules; k++ ) {
83 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
86 // `k` is assumed to be less than `giNumBuiltinModules`
88 // If a dependency failed, skip and mark as failed
89 if( baIsLoaded[k] == -1 ) {
94 // If a dependency is not intialised, skip
95 if( !baIsLoaded[k] ) break;
97 // Check if we broke out
98 if( deps[j] ) continue;
101 // All Dependencies OK? Initialise
102 StartupPrint(gKernelModules[i].Name);
103 Log("Initialising %p '%s' v%i.%i...",
105 gKernelModules[i].Name,
106 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
108 if( gKernelModules[i].Init(NULL) == 0 ) {
109 Log("Loading Failed, all modules that depend on this will also fail");
123 * \brief Registers a tModuleLoader with the kernel
124 * \param Loader Pointer to loader structure (must be persistent)
126 int Module_RegisterLoader(tModuleLoader *Loader)
128 if(!Loader) return 1;
130 Loader->Next = gModule_Loaders;
131 gModule_Loaders = Loader;
137 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
138 * \brief Load a module from a memory location
140 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
142 char path[VFS_MEMPATH_SIZE];
144 VFS_GetMemPath(path, Buffer, Length);
146 return Module_LoadFile( path, ArgString );
150 * \fn int Module_LoadFile(char *Path, char *ArgString)
151 * \brief Load a module from a file
153 int Module_LoadFile(char *Path, char *ArgString)
159 base = Binary_LoadKernel(Path);
163 Warning("Module_LoadFile: Unable to load '%s'", Path);
167 // Check for Acess Driver
168 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
171 for( tmp = gModule_Loaders; tmp; tmp = tmp->Next)
173 if( tmp->Detector(base) == 0 ) continue;
175 return tmp->Loader(base);
179 // Check for EDI Driver
180 if( Binary_FindSymbol(base, "driver_init", NULL ) != 0 )
182 return Module_InitEDI( base ); // And intialise
186 // Unknown module type?, return error
189 Warning("Module_LoadFile: Module has neither a Module Info struct, nor an EDI entrypoint");
191 Warning("Module_LoadFile: Module does not have a Module Info struct");
196 // Check magic number
197 if(info->Magic != MODULE_MAGIC)
199 Warning("Module_LoadFile: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
203 // Check Architecture
204 if(info->Arch != MODULE_ARCH_ID)
206 Warning("Module_LoadFile: Module is for a different architecture");
210 // Resolve Dependencies
211 if( !Module_int_ResolveDeps(info) ) {
216 Log("Initialising %p '%s' v%i.%i...",
219 info->Version>>8, info->Version & 0xFF
223 //if( info->Init( ArgString ) != 0 )
224 if( info->Init( NULL ) == 0 )
231 LOCK( &giModuleSpinlock );
232 info->Next = gLoadedModules;
233 gLoadedModules = info;
234 RELEASE( &giModuleSpinlock );
240 * \fn int Module_int_ResolveDeps(tModule *Info)
241 * \brief Resolves the dependencies
243 * \note Currently does not resolve the dependencies, just checks them
245 int Module_int_ResolveDeps(tModule *Info)
247 char **names = Info->Dependencies;
249 // Walk dependencies array
250 for( ; *names; names++ )
252 // Check if the module is loaded
253 if( !Module_IsLoaded(*names) ) {
254 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
262 * \fn int Module_IsLoaded(char *Name)
263 * \brief Checks if a module is loaded
264 * \param Name Name of module to find
266 int Module_IsLoaded(char *Name)
268 tModule *mod = gLoadedModules;
271 for( ; mod; mod = mod->Next )
273 // If found, return true
274 if(strcmp(mod->Name, Name) == 0)
277 // not found - return false