--- /dev/null
+/*
+ * Acess 2 Kernel
+ * - By John Hodge (thePowersGang)
+ * system.c
+ * - Architecture Independent System Init
+ */
+#define DEBUG 0
+#include <acess.h>
+
+// === IMPORTS ===
+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 *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);
+
+// === GLOBALS ===
+const char *gsInitBinary = "/Acess/SBin/init";
+char *argv[32];
+ int argc;
+
+// === CODE ===
+void System_Init(char *CommandLine)
+{
+ // Parse Kernel's Command Line
+ System_ParseCommandLine(CommandLine);
+
+ // Initialise modules
+ Log_Log("Config", "Initialising builtin modules...");
+ Modules_LoadBuiltins();
+ Arch_LoadBootModules();
+
+ System_ExecuteCommandLine();
+
+ // - Execute the Config Script
+ 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");
+}
+
+/**
+ * \fn void System_ParseCommandLine(char *ArgString)
+ * \brief Parses the kernel's command line and sets the environment
+ */
+void System_ParseCommandLine(char *ArgString)
+{
+ int i;
+ char *str;
+
+ Log_Log("Config", "Kernel Invocation (%p) \"%s\"", ArgString, ArgString);
+
+ // --- Get Arguments ---
+ str = ArgString;
+ for( argc = 0; argc < 32; argc++ )
+ {
+ // Eat Whitespace
+ while(*str == ' ') str++;
+ // Check for the end of the string
+ if(*str == '\0') { argc--; break;}
+ argv[argc] = str;
+ if(*str == '"') {
+ while(*str && !(*str == '"' && str[-1] != '\\'))
+ str ++;
+ }
+ else {
+ while(*str && *str != ' ')
+ str++;
+ }
+ 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 (Pass 1) ---
+ for( i = 1; i < argc; i++ )
+ {
+ 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;
+ }
+ }
+}
+
+/**
+ * \fn void System_ParseVFS(char *Arg)
+ */
+void System_ParseVFS(char *Arg)
+{
+ char *value;
+ int fd;
+
+ value = Arg;
+ // Search for the '=' token
+ while( *value && *value != '=' )
+ value++;
+
+ // Check if the equals was found
+ if( *value == '\0' ) {
+ Log_Warning("Config", "Expected '=' in the string '%s'", Arg);
+ return ;
+ }
+
+ // Edit string
+ *value = '\0'; value ++;
+
+ // Check assignment type
+ // - Symbolic Link <link>=<destination>
+ if(value[0] == '/')
+ {
+ Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
+ VFS_Symlink(Arg, value);
+ }
+ // - Mount <mountpoint>=<fs>:<device>
+ else
+ {
+ char *dev = value;
+ // Find colon
+ while(*dev && *dev != ':') dev++;
+ if(*dev) {
+ *dev = '\0';
+ dev++; // Eat ':'
+ }
+ // Create Mountpoint
+ if( (fd = VFS_Open(Arg, 0)) == -1 ) {
+ Log_Log("Config", "Creating directory '%s'", Arg, value);
+ VFS_MkDir( Arg );
+ } else {
+ VFS_Close(fd);
+ }
+ // Mount
+ 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)
+ */
+void System_ParseSetting(char *Arg)
+{
+ char *value;
+ value = Arg;
+
+ // Search for the '=' token
+ while( *value && *value != '=' )
+ value++;
+
+ // Check for boolean/flag (no '=')
+ if(*value == '\0')
+ {
+ //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, "INIT") == 0) {
+ Log_Log("Config", "Init binary: '%s'", value);
+ if(strlen(value) == 0)
+ gsInitBinary = NULL;
+ else
+ gsInitBinary = value;
+ }
+ else {
+ Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
+ }
+
+ }
+}
+