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;
32 int Modules_LoadBuiltins()
39 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
40 giNumBuiltinModules /= sizeof(tModule);
42 baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
44 // Pass 1 - Are the dependencies compiled in?
45 for( i = 0; i < giNumBuiltinModules; i++ )
47 deps = gKernelModules[i].Dependencies;
50 for( j = 0; deps[j]; j++ )
52 for( k = 0; k < giNumBuiltinModules; k++ ) {
53 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
56 if(k == giNumBuiltinModules) {
57 Warning("Unable to find dependency '%s' for '%s' in kernel",
58 deps[j], gKernelModules[i].Name);
60 baIsLoaded[i] = -1; // Don't Load
71 for( i = 0; i < giNumBuiltinModules; i++ )
73 if( baIsLoaded[i] ) continue; // Ignore already loaded modules
75 deps = gKernelModules[i].Dependencies;
79 for( j = 0; deps[j]; j++ )
81 for( k = 0; k < giNumBuiltinModules; k++ ) {
82 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
85 // `k` is assumed to be less than `giNumBuiltinModules`
87 // If a dependency failed, skip and mark as failed
88 if( baIsLoaded[k] == -1 ) {
93 // If a dependency is not intialised, skip
94 if( !baIsLoaded[k] ) break;
96 // Check if we broke out
97 if( deps[j] ) continue;
100 // All Dependencies OK? Initialise
101 StartupPrint(gKernelModules[i].Name);
102 Log("Initialising %p '%s' v%i.%i...",
104 gKernelModules[i].Name,
105 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
107 if( gKernelModules[i].Init(NULL) == 0 ) {
108 Log("Loading Failed, all modules that depend on this will also fail");
122 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
123 * \brief Load a module from a memory location
125 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
127 char path[VFS_MEMPATH_SIZE];
129 VFS_GetMemPath(path, Buffer, Length);
131 return Module_LoadFile( path, ArgString );
135 * \fn int Module_LoadFile(char *Path, char *ArgString)
136 * \brief Load a module from a file
138 int Module_LoadFile(char *Path, char *ArgString)
144 base = Binary_LoadKernel(Path);
148 Warning("Module_LoadFile: Unable to load '%s'", Path);
152 // Check for Acess Driver
153 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
156 // Check for EDI Driver
157 if( Binary_FindSymbol(base, "driver_init", NULL ) != 0 )
159 Binary_Relocate(base); // Relocate
160 return Module_InitEDI( base ); // And intialise
165 if( Binary_FindSymbol(base, "udi_init_info", NULL ) != 0 )
167 Binary_Relocate(base); // Relocate
168 return UDI_LoadDriver( base ); // And intialise
172 // Unknown module type?, return error
175 Warning("Module_LoadFile: Module has neither a Module Info struct, nor an EDI entrypoint");
177 Warning("Module_LoadFile: Module does not have a Module Info struct");
182 // Check magic number
183 if(info->Magic != MODULE_MAGIC)
185 Warning("Module_LoadFile: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
189 // Check Architecture
190 if(info->Arch != MODULE_ARCH_ID)
192 Warning("Module_LoadFile: Module is for a different architecture");
196 // Resolve Dependencies
197 if( !Module_int_ResolveDeps(info) ) {
202 Log("Initialising %p '%s' v%i.%i...",
205 info->Version>>8, info->Version & 0xFF
209 //if( info->Init( ArgString ) != 0 )
210 if( info->Init( NULL ) == 0 )
217 LOCK( &giModuleSpinlock );
218 info->Next = gLoadedModules;
219 gLoadedModules = info;
220 RELEASE( &giModuleSpinlock );
226 * \fn int Module_int_ResolveDeps(tModule *Info)
227 * \brief Resolves the dependencies
229 * \note Currently does not resolve the dependencies, just checks them
231 int Module_int_ResolveDeps(tModule *Info)
233 char **names = Info->Dependencies;
235 // Walk dependencies array
236 for( ; *names; names++ )
238 // Check if the module is loaded
239 if( !Module_IsLoaded(*names) ) {
240 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
248 * \fn int Module_IsLoaded(char *Name)
249 * \brief Checks if a module is loaded
250 * \param Name Name of module to find
252 int Module_IsLoaded(char *Name)
254 tModule *mod = gLoadedModules;
257 for( ; mod; mod = mod->Next )
259 // If found, return true
260 if(strcmp(mod->Name, Name) == 0)
263 // not found - return false