/*
- * Acess 2
- * Architecture Independent System Init
+ * Acess 2 Kernel
+ * - By John Hodge (thePowersGang)
* system.c
+ * - Architecture Independent System Init
*/
-#include <common.h>
+#define DEBUG 0
+#include <acess.h>
// === IMPORTS ===
-extern int Modules_LoadBuiltins();
-extern int PCI_Install();
-extern void DMA_Install();
-extern void Debug_SetKTerminal(char *File);
-extern void StartupPrint(char *Str);
+extern void Arch_LoadBootModules(void);
+extern int Modules_LoadBuiltins(void);
+extern void Modules_SetBuiltinParams(char *Name, char *ArgString);
+extern void Debug_SetKTerminal(const char *File);
// === PROTOTYPES ===
-void System_Init(char *ArgString);
+void System_Init(char *Commandline);
void System_ParseCommandLine(char *ArgString);
+void System_ExecuteCommandLine(void);
void System_ParseVFS(char *Arg);
+void System_ParseModuleArgs(char *Arg);
void System_ParseSetting(char *Arg);
-void System_ExecuteScript();
- int System_Int_GetString(char *Str, char **Dest);
// === GLOBALS ===
-char *gsConfigScript = "/Acess/Conf/BootConf.cfg";
+const char *gsInitBinary = "/Acess/SBin/init";
+char *argv[32];
+ int argc;
// === CODE ===
-void System_Init(char *ArgString)
+void System_Init(char *CommandLine)
{
- // - Start Builtin Drivers & Filesystems
- StartupPrint("Scanning PCI Bus...");
- PCI_Install();
- StartupPrint("Loading DMA...");
- DMA_Install();
- StartupPrint("Loading staticly compiled modules...");
- Modules_LoadBuiltins();
+ // Parse Kernel's Command Line
+ System_ParseCommandLine(CommandLine);
- // Set the debug to be echoed to the terminal
- StartupPrint("Kernel now echoes to VT6 (Ctrl-Alt-F7)");
- Debug_SetKTerminal("/Devices/VTerm/6");
+ // Initialise modules
+ Log_Log("Config", "Initialising builtin modules...");
+ Modules_LoadBuiltins();
+ Arch_LoadBootModules();
- // - Parse Kernel's Command Line
- System_ParseCommandLine(ArgString);
+ System_ExecuteCommandLine();
// - Execute the Config Script
- Log("Executing config script...");
- System_ExecuteScript();
+ Log_Log("Config", "Spawning init '%s'", gsInitBinary);
+ Proc_Spawn(gsInitBinary);
+
+ // Set the debug to be echoed to the terminal
+ Log_Log("Config", "Kernel now echoes to VT7 (Ctrl-Alt-F8)");
+ Debug_SetKTerminal("/Devices/VTerm/7");
}
/**
*/
void System_ParseCommandLine(char *ArgString)
{
- char *argv[32];
- int argc;
int i;
char *str;
- Log("Kernel Command Line: \"%s\"", ArgString);
+ Log_Log("Config", "Kernel Invocation (%p) \"%s\"", ArgString, ArgString);
// --- Get Arguments ---
str = ArgString;
for( argc = 0; argc < 32; argc++ )
{
- while(*str == ' ') str++; // Eat Whitespace
- if(*str == '\0') { argc--; break;} // End of string
+ // Eat Whitespace
+ while(*str == ' ') str++;
+ // Check for the end of the string
+ if(*str == '\0') { argc--; break;}
argv[argc] = str;
- while(*str && *str != ' ')
- {
- /*if(*str == '"') {
- while(*str && !(*str == '"' && str[-1] != '\\'))
- str ++;
- }*/
- str++;
+ if(*str == '"') {
+ while(*str && !(*str == '"' && str[-1] != '\\'))
+ str ++;
+ }
+ else {
+ while(*str && *str != ' ')
+ str++;
}
- if(*str == '\0') break; // End of string
+ if(*str == '\0') break; // Check for EOS
*str = '\0'; // Cap off argument string
str ++; // and increment the string pointer
}
if(argc < 32)
argc ++; // Count last argument
- // --- Parse Arguments ---
+ // --- Parse Arguments (Pass 1) ---
for( i = 1; i < argc; i++ )
{
- if( argv[i][0] == '/' )
- System_ParseVFS( argv[i] );
- else
+ switch(argv[i][0])
+ {
+ // --- VFS ---
+ // Ignored on this pass
+ case '/':
+ break;
+
+ // --- Module Paramaters ---
+ // -VTerm:Width=640,Height=480,Scrollback=2
+ case '-':
+ System_ParseModuleArgs( argv[i] );
+ break;
+ // --- Config Options ---
+ // SCRIPT=/Acess/Conf/BootConf.cfg
+ default:
System_ParseSetting( argv[i] );
+ break;
+ }
+ }
+}
+
+void System_ExecuteCommandLine(void)
+{
+ int i;
+ if(argc > 0)
+ LOG("Invocation '%s'", argv[0]);
+ for( i = 1; i < argc; i++ )
+ {
+ LOG("argv[%i] = '%s'", i, argv[i]);
+ switch(argv[i][0])
+ {
+ // --- VFS ---
+ // Mount /System=ext2:/Devices/ATA/A1
+ // Symlink /Acess=/System/Acess2
+ case '/':
+ System_ParseVFS( argv[i] );
+ break;
+ }
}
}
// Check if the equals was found
if( *value == '\0' ) {
- Warning("Expected '=' in the string '%s'", Arg);
+ Log_Warning("Config", "Expected '=' in the string '%s'", Arg);
return ;
}
// - Symbolic Link <link>=<destination>
if(value[0] == '/')
{
- Log("Symbolic link '%s' pointing to '%s'", Arg, value);
+ Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
VFS_Symlink(Arg, value);
}
// - Mount <mountpoint>=<fs>:<device>
}
// Create Mountpoint
if( (fd = VFS_Open(Arg, 0)) == -1 ) {
- Log("Creating directory '%s'", Arg, value);
+ Log_Log("Config", "Creating directory '%s'", Arg, value);
VFS_MkDir( Arg );
} else {
VFS_Close(fd);
}
// Mount
- Log("Mounting '%s' to '%s' ('%s')", dev, Arg, value);
+ Log_Log("Config", "Mounting '%s' to '%s' ('%s')", dev, Arg, value);
VFS_Mount(dev, Arg, value, "");
}
}
+/**
+ * \brief Parse a module argument string
+ * \param Arg Argument string
+ */
+void System_ParseModuleArgs(char *Arg)
+{
+ char *name, *args;
+ int i;
+
+ // Remove '-'
+ name = Arg + 1;
+
+ // Find the start of the args
+ i = strpos(name, ':');
+ if( i == -1 ) {
+ Log_Warning("Config", "Module spec with no arguments");
+ #if 1
+ return ;
+ #else
+ i = strlen(name);
+ args = name + i;
+ #endif
+ }
+ else {
+ name[i] = '\0';
+ args = name + i + 1;
+ }
+
+ Log_Log("Config", "Setting boot parameters for '%s' to '%s'", name, args);
+ Modules_SetBuiltinParams(name, args);
+}
+
/**
* \fn void System_ParseSetting(char *Arg)
*/
// Check for boolean/flag (no '=')
if(*value == '\0')
{
- if(strcmp(Arg, "") == 0) {
- } else {
- Warning("Kernel flag '%s' is not recognised", Arg);
- }
+ //if(strcmp(Arg, "") == 0) {
+ //} else {
+ Log_Warning("Config", "Kernel flag '%s' is not recognised", Arg);
+ //}
}
else
{
*value = '\0'; // Remove '='
value ++; // and eat it's position
- if(strcmp(Arg, "SCRIPT") == 0) {
- Log("Config Script: '%s'", value);
- gsConfigScript = value;
- } else {
- Warning("Kernel config setting '%s' is not recognised", Arg);
- }
-
- }
-}
-
-/**
- * \fn void System_ExecuteScript()
- */
-void System_ExecuteScript()
-{
- int fp;
- int fLen = 0;
- int i = 0, lineStart;
- char *sArg1, *sArg2, *sArg3;
- char *fData;
-
- // Open Script
- fp = VFS_Open(gsConfigScript, VFS_OPENFLAG_READ);
- if(fp == -1) {
- Warning("[CFG] Passed script '%s' does not exist", gsConfigScript);
- return;
- }
-
- // Read into memory buffer
- VFS_Seek(fp, 0, SEEK_END);
- fLen = VFS_Tell(fp);
- VFS_Seek(fp, 0, SEEK_SET);
- fData = malloc(fLen+1);
- VFS_Read(fp, fLen, fData);
- fData[fLen] = '\0';
- VFS_Close(fp);
-
- // Read Script
- while(i < fLen)
- {
- sArg1 = sArg2 = sArg3 = NULL;
-
- lineStart = i;
- // Clear leading whitespace and find empty lines
- while(i < fLen && (fData[i] == ' ' || fData[i]=='\t')) i ++;
- if(i == fLen) break;
- if(fData[i] == '\n') {
- i++;
- continue;
- }
-
- // Comment
- if(fData[i] == ';' || fData[i] == '#') {
- while(i < fLen && fData[i] != '\n') i ++;
- i ++;
- continue;
- }
-
- // Commands
- // - Mount
- if(strncmp("mount ", fData+i, 6) == 0) {
- i += 6;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- i += System_Int_GetString(fData+i, &sArg2);
- if(!sArg2) goto read2eol;
- i += System_Int_GetString(fData+i, &sArg3);
- if(!sArg3) goto read2eol;
- //Log("[CFG ] Mount '%s' to '%s' (%s)\n", sArg1, sArg2, sArg3);
- VFS_Mount(sArg1, sArg2, sArg3, "");
- }
- // - Load Module
- else if(strncmp("module ", fData+i, 6) == 0) {
- //char *tmp;
- i += 7;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- Module_LoadFile(sArg1, ""); //!\todo Use the rest of the line as the argument string
- }
- // - Load Module
- else if(strncmp("edimod ", fData+i, 6) == 0) {
- i += 7;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- Log("[CFG ] Load EDI Module '%s'\n", sArg1);
- Module_LoadFile(sArg1, "");
- }
- // - Symlink
- else if(strncmp("symlink ", fData+i, 7) == 0) {
- i += 8;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- i += System_Int_GetString(fData+i, &sArg2);
- if(!sArg2) goto read2eol;
- Log("[CFG ] Symlink '%s' pointing to '%s'\n", sArg1, sArg2);
- VFS_Symlink(sArg1, sArg2);
- }
- // - New Directory
- else if(strncmp("mkdir ", fData+i, 5) == 0) {
- i += 6;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- Log("[CFG ] New Directory '%s'\n", sArg1);
- VFS_MkDir(sArg1);
- }
- // - Spawn a task
- else if(strncmp("spawn ", fData+i, 5) == 0) {
- i += 6;
- i += System_Int_GetString(fData+i, &sArg1);
- if(!sArg1) goto read2eol;
- Log("[CFG ] Starting '%s' as a new task\n", sArg1);
- Proc_Spawn(sArg1);
+ if(strcmp(Arg, "INIT") == 0) {
+ Log_Log("Config", "Init binary: '%s'", value);
+ if(strlen(value) == 0)
+ gsInitBinary = NULL;
+ else
+ gsInitBinary = value;
}
else {
- Warning("Unknown configuration command, Line: '%s'", fData+i);
- goto read2eol;
+ Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
}
- read2eol:
- if(sArg1) free(sArg1);
- if(sArg2) free(sArg2);
- if(sArg3) free(sArg3);
- // Skip to EOL
- while(i < fLen && fData[i] != '\n') i++;
- i ++; // Skip \n
- }
- free(fData);
-}
-
-/**
- * \fn int System_Int_GetString(char *Str, char **Dest)
- * \brief Gets a string from another
- * \note Destructive
- * \param Str Input String
- * \param Dest Pointer to output pointer
- * \return Characters eaten from input
- */
-int System_Int_GetString(char *Str, char **Dest)
-{
- int pos = 0;
- int start = 0;
- int len;
-
- //LogF("GetString: (Str='%s', Dest=0x%x)\n", Str, Dest);
-
- while(Str[pos] == ' ' || Str[pos] == '\t') pos++;
- if(Str[pos] == '\n' || Str[pos] == '\0') {
- *Dest = NULL;
- return pos;
- }
-
- // Quoted String
- if(Str[pos] == '"')
- {
- pos ++;
- start = pos;
- while(Str[pos] != '"') pos++;
-
- len = pos - start;
- *Dest = malloc( len + 1 );
- memcpy( *Dest, Str+start, len );
- (*Dest)[len] = '\0';
- //LogF("GetString: RETURN *Dest = '%s'\n", *Dest);
-
- pos++;
- return pos;
}
-
- // Non-Quoted String - Whitespace deliminated
- start = pos;
- while(Str[pos] != ' ' && Str[pos] != '\t' && Str[pos] != '\n') pos++;
-
- len = pos - start;
- //LogF(" GetString: len = %i\n", len);
- *Dest = malloc( len + 1 );
- memcpy( *Dest, Str+start, len );
- (*Dest)[len] = '\0';
-
- //LogF("GetString: RETURN *Dest = '%s'\n", *Dest);
-
- return pos;
}
+