3 * - By John Hodge (thePowersGang)
5 * - Architecture Independent System Init
12 extern void Arch_LoadBootModules(void);
13 extern int Modules_LoadBuiltins(void);
14 extern void Modules_SetBuiltinParams(char *Name, char *ArgString);
15 extern void Debug_SetKTerminal(const char *File);
16 extern void Timer_CallbackThread(void *);
17 extern void EmergencyConsole(void);
20 void System_Init(char *Commandline);
21 void System_ParseCommandLine(char *ArgString);
22 void System_ExecuteCommandLine(void);
23 void System_ParseVFS(char *Arg);
24 void System_ParseModuleArgs(char *Arg);
25 void System_ParseSetting(char *Arg);
26 void System_EmergencyConsole(void);
29 const char *gsInitBinary = "/Acess/SBin/init";
34 void System_Init(char *CommandLine)
36 Proc_SpawnWorker(Timer_CallbackThread, NULL);
38 // Parse Kernel's Command Line
39 System_ParseCommandLine(CommandLine);
42 Log_Log("Config", "Initialising builtin modules...");
43 Modules_LoadBuiltins();
44 Arch_LoadBootModules();
46 Log_Log("Config", "Running command line '%s", CommandLine);
47 System_ExecuteCommandLine();
49 // - Execute the Config Script
50 Log_Log("Config", "Spawning init '%s'", gsInitBinary);
51 if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0)
53 const char *args[] = {gsInitBinary, 0};
54 VFS_Open("/Devices/pts/vt0", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER); // 0: stdin
55 VFS_Open("/Devices/pts/vt0", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER); // 1: stdout
56 VFS_DuplicateFD(1, 2); // 2: stderr
57 Proc_Execve(gsInitBinary, args, &args[1], 0);
59 System_EmergencyConsole();
61 Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary);
64 // Set the debug to be echoed to the terminal
65 Log_Log("Config", "Kernel now echoes to VT7 (Ctrl-Alt-F8)");
66 Debug_SetKTerminal("/Devices/pts/vt7");
68 // Run a thread to reap unowned threads
72 // TODO: Inform init when a thread dies
73 int tid = Threads_WaitTID(-1, &status);
74 Log_Debug("Thread0", "Thread %i exited with status %i", tid, status);
79 * \fn void System_ParseCommandLine(char *ArgString)
80 * \brief Parses the kernel's command line and sets the environment
82 void System_ParseCommandLine(char *ArgString)
87 Log_Log("Config", "Kernel Invocation (%p) \"%s\"", ArgString, ArgString);
89 // --- Get Arguments ---
91 for( argc = 0; argc < 32; argc++ )
94 while(*str == ' ') str++;
95 // Check for the end of the string
102 while(*str && !(*str == '"' && str[-1] != '\\'))
106 while(*str && *str != ' ')
109 if(*str == '\0') break; // Check for EOS
110 *str = '\0'; // Cap off argument string
111 str ++; // and increment the string pointer
114 argc ++; // Count last argument
116 // --- Parse Arguments (Pass 1) ---
117 for( i = 1; i < argc; i++ )
122 // Ignored on this pass
126 // --- Module Paramaters ---
127 // -VTerm:Width=640,Height=480,Scrollback=2
129 System_ParseModuleArgs( argv[i] );
131 // --- Config Options ---
132 // SCRIPT=/Acess/Conf/BootConf.cfg
134 System_ParseSetting( argv[i] );
140 void System_ExecuteCommandLine(void)
144 LOG("Invocation '%s'", argv[0]);
145 for( i = 1; i < argc; i++ )
147 LOG("argv[%i] = '%s'", i, argv[i]);
151 // Mount /System=ext2:/Devices/ATA/A1
152 // Symlink /Acess=/System/Acess2
154 System_ParseVFS( argv[i] );
161 * \fn void System_ParseVFS(char *Arg)
163 void System_ParseVFS(char *Arg)
169 // Search for the '=' token
170 while( *value && *value != '=' )
173 // Check if the equals was found
174 if( *value == '\0' ) {
175 Log_Warning("Config", "Expected '=' in the string '%s'", Arg);
180 *value = '\0'; value ++;
182 // Check assignment type
183 // - Symbolic Link <link>=<destination>
186 // Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
187 VFS_Symlink(Arg, value);
189 // - Mount <mountpoint>=<fs>:<device>
194 while(*dev && *dev != ':') dev++;
200 if( (fd = VFS_Open(Arg, 0)) == -1 ) {
201 // Log_Log("Config", "Creating directory '%s'", Arg, value);
207 // Log_Log("Config", "Mounting '%s' to '%s' ('%s')", dev, Arg, value);
208 VFS_Mount(dev, Arg, value, "");
213 * \brief Parse a module argument string
214 * \param Arg Argument string
216 void System_ParseModuleArgs(char *Arg)
224 // Find the start of the args
225 i = strpos(name, ':');
227 Log_Warning("Config", "Module spec with no arguments");
240 Log_Log("Config", "Setting boot parameters for '%s' to '%s'", name, args);
241 Modules_SetBuiltinParams(name, args);
245 * \fn void System_ParseSetting(char *Arg)
247 void System_ParseSetting(char *Arg)
252 // Search for the '=' token
253 while( *value && *value != '=' )
256 // Check for boolean/flag (no '=')
259 //if(strcmp(Arg, "") == 0) {
261 Log_Warning("Config", "Kernel flag '%s' is not recognised", Arg);
266 *value = '\0'; // Remove '='
267 value ++; // and eat it's position
269 if(strcmp(Arg, "INIT") == 0) {
270 Log_Log("Config", "Init binary: '%s'", value);
271 if(strlen(value) == 0)
274 gsInitBinary = value;
277 Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
283 void System_EmergencyConsole(void)
285 // TODO: Support an emergency kernel-land console (with FS viewing support)