9 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString);
10 int Module_LoadFile(char *Path, char *ArgString);
11 int Module_int_ResolveDeps(tModule *Info);
12 int Module_IsLoaded(char *Name);
15 extern void StartupPrint(char *Str);
16 extern tModule gKernelModules[];
17 extern void gKernelModulesEnd;
20 int giNumBuiltinModules = 0;
21 int giModuleSpinlock = 0;
22 tModule *gLoadedModules = NULL;
25 int Modules_LoadBuiltins()
32 giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
33 giNumBuiltinModules /= sizeof(tModule);
35 baIsLoaded = calloc( giNumBuiltinModules, sizeof(*baIsLoaded) );
37 // Pass 1 - Are the dependencies compiled in?
38 for( i = 0; i < giNumBuiltinModules; i++ )
40 deps = gKernelModules[i].Dependencies;
43 for( j = 0; deps[j]; j++ )
45 for( k = 0; k < giNumBuiltinModules; k++ ) {
46 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
49 Log("%s requires %s\n", gKernelModules[i].Name, deps[j]);
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 Log("baIsLoaded[%i(%s)] = %i\n", k, deps[j], baIsLoaded[k]);
82 // If a dependency failed, skip and mark as failed
83 if( baIsLoaded[k] == -1 ) {
88 // If a dependency is not intialised, skip
89 if( !baIsLoaded[k] ) break;
91 // Check if we broke out
92 if( deps[j] ) continue;
95 // All Dependencies OK? Initialise
96 StartupPrint(gKernelModules[i].Name);
97 Log("Initialising %p '%s' v%i.%i...",
99 gKernelModules[i].Name,
100 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
102 gKernelModules[i].Init(NULL);
113 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
114 * \brief Load a module from a memory location
116 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
118 char path[VFS_MEMPATH_SIZE];
120 VFS_GetMemPath(Buffer, Length, path);
122 return Module_LoadFile( path, ArgString );
126 * \fn int Module_LoadFile(char *Path, char *ArgString)
127 * \brief Load a module from a file
129 int Module_LoadFile(char *Path, char *ArgString)
135 base = Binary_LoadKernel(Path);
138 if(base == NULL) return 0;
140 // Check for Acess Driver
141 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
144 // Check for EDI Driver
145 if( Binary_FindSymbol(base, "driver_init", NULL ) == 0 )
147 Binary_Relocate(base); // Relocate
148 return Module_InitEDI( base ); // And intialise
152 // Unknown module type?, return error
155 Warning("Module_LoadMem: Module has neither a Module Info struct, nor an EDI entrypoint");
157 Warning("Module_LoadMem: Module does not have a Module Info struct");
162 // Check magic number
163 if(info->Magic != MODULE_MAGIC)
165 Warning("Module_LoadMem: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
169 // Check Architecture
170 if(info->Arch != MODULE_ARCH_ID)
172 Warning("Module_LoadMem: Module is for a different architecture");
176 // Resolve Dependencies
177 if( !Module_int_ResolveDeps(info) ) {
182 Log("Initialising %p '%s' v%i.%i...",
185 info->Version>>8, info->Version & 0xFF
189 //if( info->Init( ArgString ) != 0 )
190 if( info->Init( NULL ) == 0 )
197 LOCK( &giModuleSpinlock );
198 info->Next = gLoadedModules;
199 gLoadedModules = info;
200 RELEASE( &giModuleSpinlock );
206 * \fn int Module_int_ResolveDeps(tModule *Info)
207 * \brief Resolves the dependencies
209 * \note Currently does not resolve the dependencies, just checks them
211 int Module_int_ResolveDeps(tModule *Info)
213 char **names = Info->Dependencies;
215 // Walk dependencies array
216 for( ; *names; names++ )
218 // Check if the module is loaded
219 if( !Module_IsLoaded(*names) ) {
220 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
228 * \fn int Module_IsLoaded(char *Name)
229 * \brief Checks if a module is loaded
230 * \param Name Name of module to find
232 int Module_IsLoaded(char *Name)
234 tModule *mod = gLoadedModules;
237 for( ; mod; mod = mod->Next )
239 // If found, return true
240 if(strcmp(mod->Name, Name) == 0)
243 // not found - return false