9 int Modules_LoadBuiltins();
10 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
11 int Module_LoadFile(char *Path, char *ArgString);
12 int Module_int_ResolveDeps(tModule *Info);
13 int Module_IsLoaded(char *Name);
16 extern void StartupPrint(char *Str);
17 extern tModule gKernelModules[];
18 extern void gKernelModulesEnd;
21 int giNumBuiltinModules = 0;
22 int giModuleSpinlock = 0;
23 tModule *gLoadedModules = NULL;
26 int Modules_LoadBuiltins()
33 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
34 giNumBuiltinModules /= sizeof(tModule);
36 baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
38 // Pass 1 - Are the dependencies compiled in?
39 for( i = 0; i < giNumBuiltinModules; i++ )
41 deps = gKernelModules[i].Dependencies;
44 for( j = 0; deps[j]; j++ )
46 for( k = 0; k < giNumBuiltinModules; k++ ) {
47 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
50 if(k == giNumBuiltinModules) {
51 Warning("Unable to find dependency '%s' for '%s' in kernel",
52 deps[j], gKernelModules[i].Name);
54 baIsLoaded[i] = -1; // Don't Load
65 for( i = 0; i < giNumBuiltinModules; i++ )
67 if( baIsLoaded[i] ) continue; // Ignore already loaded modules
69 deps = gKernelModules[i].Dependencies;
73 for( j = 0; deps[j]; j++ )
75 for( k = 0; k < giNumBuiltinModules; k++ ) {
76 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
79 // `k` is assumed to be less than `giNumBuiltinModules`
81 // If a dependency failed, skip and mark as failed
82 if( baIsLoaded[k] == -1 ) {
87 // If a dependency is not intialised, skip
88 if( !baIsLoaded[k] ) break;
90 // Check if we broke out
91 if( deps[j] ) continue;
94 // All Dependencies OK? Initialise
95 StartupPrint(gKernelModules[i].Name);
96 Log("Initialising %p '%s' v%i.%i...",
98 gKernelModules[i].Name,
99 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
101 if( gKernelModules[i].Init(NULL) == 0 ) {
102 Log("Loading Failed, all modules that depend on this will also fail");
116 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
117 * \brief Load a module from a memory location
119 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
121 char path[VFS_MEMPATH_SIZE];
123 VFS_GetMemPath(path, Buffer, Length);
125 return Module_LoadFile( path, ArgString );
129 * \fn int Module_LoadFile(char *Path, char *ArgString)
130 * \brief Load a module from a file
132 int Module_LoadFile(char *Path, char *ArgString)
138 base = Binary_LoadKernel(Path);
141 if(base == NULL) return 0;
143 // Check for Acess Driver
144 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
147 // Check for EDI Driver
148 if( Binary_FindSymbol(base, "driver_init", NULL ) == 0 )
150 Binary_Relocate(base); // Relocate
151 return Module_InitEDI( base ); // And intialise
155 // Unknown module type?, return error
158 Warning("Module_LoadMem: Module has neither a Module Info struct, nor an EDI entrypoint");
160 Warning("Module_LoadMem: Module does not have a Module Info struct");
165 // Check magic number
166 if(info->Magic != MODULE_MAGIC)
168 Warning("Module_LoadMem: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
172 // Check Architecture
173 if(info->Arch != MODULE_ARCH_ID)
175 Warning("Module_LoadMem: Module is for a different architecture");
179 // Resolve Dependencies
180 if( !Module_int_ResolveDeps(info) ) {
185 Log("Initialising %p '%s' v%i.%i...",
188 info->Version>>8, info->Version & 0xFF
192 //if( info->Init( ArgString ) != 0 )
193 if( info->Init( NULL ) == 0 )
200 LOCK( &giModuleSpinlock );
201 info->Next = gLoadedModules;
202 gLoadedModules = info;
203 RELEASE( &giModuleSpinlock );
209 * \fn int Module_int_ResolveDeps(tModule *Info)
210 * \brief Resolves the dependencies
212 * \note Currently does not resolve the dependencies, just checks them
214 int Module_int_ResolveDeps(tModule *Info)
216 char **names = Info->Dependencies;
218 // Walk dependencies array
219 for( ; *names; names++ )
221 // Check if the module is loaded
222 if( !Module_IsLoaded(*names) ) {
223 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
231 * \fn int Module_IsLoaded(char *Name)
232 * \brief Checks if a module is loaded
233 * \param Name Name of module to find
235 int Module_IsLoaded(char *Name)
237 tModule *mod = gLoadedModules;
240 for( ; mod; mod = mod->Next )
242 // If found, return true
243 if(strcmp(mod->Name, Name) == 0)
246 // not found - return false