+ LOG("ret = %i", ret);
+
+ // Remove from loading list
+ gLoadingModules = gLoadingModules->Next;
+
+ // Add to loaded list
+ LOCK( &glModuleSpinlock );
+ Module->Next = gLoadedModules;
+ gLoadedModules = Module;
+ RELEASE( &glModuleSpinlock );
+
+ LEAVE_RET('i', 0);
+}
+
+/**
+ * \brief Initialises builtin modules
+ */
+void Modules_LoadBuiltins()
+{
+ int i;
+
+ // Count modules
+ giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
+ giNumBuiltinModules /= sizeof(tModule);
+
+ for( i = 0; i < giNumBuiltinModules; i++ )
+ {
+ Module_int_Initialise(
+ &gKernelModules[i],
+ (gasBuiltinModuleArgs ? gasBuiltinModuleArgs[i] : NULL)
+ );
+ }
+
+ if( gasBuiltinModuleArgs != NULL )
+ free(gasBuiltinModuleArgs);
+}
+
+/**
+ * \brief Sets the parameters for a builtin module
+ */
+void Modules_SetBuiltinParams(char *Name, char *ArgString)
+{
+ int i;
+ if( gasBuiltinModuleArgs == NULL ) {
+ giNumBuiltinModules = (Uint)&gKernelModulesEnd - (Uint)&gKernelModules;
+ giNumBuiltinModules /= sizeof(tModule);
+ gasBuiltinModuleArgs = calloc( giNumBuiltinModules, sizeof(char*) );
+ }
+
+ for( i = 0; i < giNumBuiltinModules; i ++ )
+ {
+ if(strcmp( gKernelModules[i].Name, Name ) == 0) {
+ gasBuiltinModuleArgs[i] = ArgString;
+ return ;
+ }
+ }
+
+ Log_Warning("Modules", "Unknown builtin kernel module '%s'", Name);
+}
+
+/**
+ * \brief Registers a tModuleLoader with the kernel
+ * \param Loader Pointer to loader structure (must be persistent)
+ */
+int Module_RegisterLoader(tModuleLoader *Loader)
+{
+ if(!Loader) return 1;
+
+ Loader->Next = gModule_Loaders;
+ gModule_Loaders = Loader;