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 if(k == giNumBuiltinModules) {
50 Warning("Unable to find dependency '%s' for '%s' in kernel",
51 deps[j], gKernelModules[i].Name);
53 baIsLoaded[i] = -1; // Don't Load
64 for( i = 0; i < giNumBuiltinModules; i++ )
66 if( baIsLoaded[i] ) continue; // Ignore already loaded modules
68 deps = gKernelModules[i].Dependencies;
72 for( j = 0; deps[j]; j++ )
74 for( k = 0; k < giNumBuiltinModules; k++ ) {
75 if(strcmp(deps[j], gKernelModules[k].Name) == 0)
78 // `k` is assumed to be less than `giNumBuiltinModules`
80 // If a dependency failed, skip and mark as failed
81 if( baIsLoaded[k] == -1 ) {
86 // If a dependency is not intialised, skip
87 if( !baIsLoaded[k] ) break;
89 // Check if we broke out
90 if( deps[j] ) continue;
93 // All Dependencies OK? Initialise
94 StartupPrint(gKernelModules[i].Name);
95 Log("Initialising %p '%s' v%i.%i...",
97 gKernelModules[i].Name,
98 gKernelModules[i].Version>>8, gKernelModules[i].Version & 0xFF
100 gKernelModules[i].Init(NULL);
111 * \fn int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
112 * \brief Load a module from a memory location
114 int Module_LoadMem(void *Buffer, Uint Length, char *ArgString)
116 char path[VFS_MEMPATH_SIZE];
118 VFS_GetMemPath(Buffer, Length, path);
120 return Module_LoadFile( path, ArgString );
124 * \fn int Module_LoadFile(char *Path, char *ArgString)
125 * \brief Load a module from a file
127 int Module_LoadFile(char *Path, char *ArgString)
133 base = Binary_LoadKernel(Path);
136 if(base == NULL) return 0;
138 // Check for Acess Driver
139 if( Binary_FindSymbol(base, "DriverInfo", (Uint*)&info ) == 0 )
142 // Check for EDI Driver
143 if( Binary_FindSymbol(base, "driver_init", NULL ) == 0 )
145 Binary_Relocate(base); // Relocate
146 return Module_InitEDI( base ); // And intialise
150 // Unknown module type?, return error
153 Warning("Module_LoadMem: Module has neither a Module Info struct, nor an EDI entrypoint");
155 Warning("Module_LoadMem: Module does not have a Module Info struct");
160 // Check magic number
161 if(info->Magic != MODULE_MAGIC)
163 Warning("Module_LoadMem: Module's magic value is invalid (0x%x != 0x%x)", info->Magic, MODULE_MAGIC);
167 // Check Architecture
168 if(info->Arch != MODULE_ARCH_ID)
170 Warning("Module_LoadMem: Module is for a different architecture");
174 // Resolve Dependencies
175 if( !Module_int_ResolveDeps(info) ) {
180 Log("Initialising %p '%s' v%i.%i...",
183 info->Version>>8, info->Version & 0xFF
187 //if( info->Init( ArgString ) != 0 )
188 if( info->Init( NULL ) == 0 )
195 LOCK( &giModuleSpinlock );
196 info->Next = gLoadedModules;
197 gLoadedModules = info;
198 RELEASE( &giModuleSpinlock );
204 * \fn int Module_int_ResolveDeps(tModule *Info)
205 * \brief Resolves the dependencies
207 * \note Currently does not resolve the dependencies, just checks them
209 int Module_int_ResolveDeps(tModule *Info)
211 char **names = Info->Dependencies;
213 // Walk dependencies array
214 for( ; *names; names++ )
216 // Check if the module is loaded
217 if( !Module_IsLoaded(*names) ) {
218 Warning("Module `%s' requires `%s', which is not loaded\n", Info->Name, *names);
226 * \fn int Module_IsLoaded(char *Name)
227 * \brief Checks if a module is loaded
228 * \param Name Name of module to find
230 int Module_IsLoaded(char *Name)
232 tModule *mod = gLoadedModules;
235 for( ; mod; mod = mod->Next )
237 // If found, return true
238 if(strcmp(mod->Name, Name) == 0)
241 // not found - return false