Kernel - Gitignore for build numbers
[tpg/acess2.git] / Kernel / system.c
index a720add..cbf828c 100644 (file)
@@ -23,61 +23,81 @@ typedef struct
 }      tConfigFile;
 typedef struct
 {
-       char    *Name;          // Name
+       const char      *Name;          // Name
         int    MinArgs;        // Minimum number of arguments
         int    MaxArgs;        // Maximum number of arguments
        Uint    IntArgs;        // Bitmap of arguments that should be treated as integers
-       void    *Func;          // Function pointer
-       Uint    OptDefaults[N_MAX_ARGS];        // Default values for optional arguments
+        int    Index;          // 
+       const char      *OptDefaults[N_MAX_ARGS];       // Default values for optional arguments
 }      tConfigCommand;
 
 // === 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();
+void   System_ExecuteScript(void);
 tConfigFile    *System_Int_ParseFile(char *File);
 
 // === CONSTANTS ===
+enum eConfigCommands {
+       CC_LOADMODULE,
+       CC_SPAWN,
+       CC_MOUNT,
+       CC_SYMLINK,
+       CC_MKDIR,
+       CC_OPEN,
+       CC_CLOSE,
+       CC_IOCTL
+};
 const tConfigCommand   caConfigCommands[] = {
-       {"module", 1,2, 0, Module_LoadFile, {(Uint)"",0}},      // Load a module from a file
-       {"spawn", 1,1, 0, Proc_Spawn, {0}},             // Spawn a process
+       {"module",  1,2, 00, CC_LOADMODULE, {"",NULL}}, // Load a module from a file
+       {"spawn",   1,1, 00, CC_SPAWN, {NULL}},         // Spawn a process
        // --- VFS ---
-       {"mount", 3,4, 0, VFS_Mount, {(Uint)"",0}},             // Mount a device
-       {"symlink", 2,2, 0, VFS_Symlink, {0}},  // Create a Symbolic Link
-       {"mkdir", 1,1, 0, VFS_MkDir, {0}},              // Create a Directory
-       {"open", 1,2, 0, VFS_Open, {VFS_OPENFLAG_READ,0}},      // Open a file
-       {"close", 1,1, 0x1, VFS_Close, {0}},    // Close an open file
-       {"ioctl", 3,3, 0x3, VFS_IOCtl, {0}},    // Call an IOCtl
+       {"mount",   3,4, 00, CC_MOUNT, {"",0}},         // Mount a device
+       {"symlink", 2,2, 00, CC_SYMLINK, {0}},  // Create a Symbolic Link
+       {"mkdir",   1,1, 00, CC_MKDIR, {0}},            // Create a Directory
+       {"open",    1,2, 00, CC_OPEN,  {(void*)VFS_OPENFLAG_READ,0}},   // Open a file
+       {"close",   1,1, 01, CC_CLOSE, {0}},    // Close an open file
+       {"ioctl",   3,3, 03, CC_IOCTL, {0}},    // Call an IOCtl
        
-       {"", 0,0, 0, NULL, {0}}
+       {"", 0,0, 0, 0, {0}}
 };
 #define NUM_CONFIG_COMMANDS    (sizeof(caConfigCommands)/sizeof(caConfigCommands[0]))
 
 // === GLOBALS ===
-char   *gsConfigScript = "/Acess/Conf/BootConf.cfg";
+const char     *gsConfigScript = "/Acess/Conf/BootConf.cfg";
+char   *argv[32];
+ int   argc;
 
 // === CODE ===
-void System_Init(char *ArgString)
-{      
-       // Set the debug to be echoed to the terminal
-       StartupPrint("Kernel now echoes to VT7 (Ctrl-Alt-F8)");
-       Debug_SetKTerminal("/Devices/VTerm/7");
+void System_Init(char *CommandLine)
+{
+       // Parse Kernel's Command Line
+       System_ParseCommandLine(CommandLine);
        
-       // - Parse Kernel's Command Line
-       System_ParseCommandLine(ArgString);
+       // Initialise modules
+       Log_Log("Config", "Initialising builtin modules...");
+       Modules_LoadBuiltins();
+       Arch_LoadBootModules();
+       
+       System_ExecuteCommandLine();
        
        // - Execute the Config Script
-       Log_Log("Config", "Executing config script...");
+       Log_Log("Config", "Executing config script '%s'", gsConfigScript);
        System_ExecuteScript();
+       
+       // 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");
 }
 
 /**
@@ -86,12 +106,11 @@ void System_Init(char *ArgString)
  */
 void System_ParseCommandLine(char *ArgString)
 {
-       char    *argv[32];
-        int    argc;
         int    i;
        char    *str;
        
-       Log_Log("Config", "Kernel Invocation \"%s\"", ArgString);
+       Log_Log("Config", "Kernel Invocation (%p) \"%s\"", ArgString, ArgString);
+       Log_Log("Config", "Kernel Invocation '0x%x 0x%x'", ArgString[0], ArgString[1]);
        
        // --- Get Arguments ---
        str = ArgString;
@@ -102,13 +121,13 @@ void System_ParseCommandLine(char *ArgString)
                // 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;  // Check for EOS
                *str = '\0';    // Cap off argument string
@@ -117,13 +136,45 @@ void System_ParseCommandLine(char *ArgString)
        if(argc < 32)
                argc ++;        // Count last argument
        
-       // --- Parse Arguments ---
-       for( i = 1; i < argc; i++ )
+       // --- Parse Arguments (Pass 1) ---
+       for( i = 0; 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;
+       for( i = 0; 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;
+               }
        }
 }
 
@@ -179,6 +230,38 @@ void System_ParseVFS(char *Arg)
        }
 }
 
+/**
+ * \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)
  */
@@ -206,7 +289,10 @@ void System_ParseSetting(char *Arg)
                
                if(strcmp(Arg, "SCRIPT") == 0) {
                        Log_Log("Config", "Config Script: '%s'", value);
-                       gsConfigScript = value;
+                       if(strlen(value) == 0)
+                               gsConfigScript = NULL;
+                       else
+                               gsConfigScript = value;
                } else {
                        Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
                }
@@ -216,8 +302,9 @@ void System_ParseSetting(char *Arg)
 
 /**
  * \fn void System_ExecuteScript()
+ * \brief Reads and parses the boot configuration script
  */
-void System_ExecuteScript()
+void System_ExecuteScript(void)
 {
         int    fp;
         int    fLen = 0;
@@ -238,10 +325,12 @@ void System_ExecuteScript()
                return;
        }
        
-       // Read into memory buffer
+       // Get length
        VFS_Seek(fp, 0, SEEK_END);
        fLen = VFS_Tell(fp);
+       Log_Debug("System", "VFS_Tell(%i) = %i", fp, fLen);
        VFS_Seek(fp, 0, SEEK_SET);
+       // Read into memory buffer
        fData = malloc(fLen+1);
        VFS_Read(fp, fLen, fData);
        fData[fLen] = '\0';
@@ -260,7 +349,8 @@ void System_ExecuteScript()
                if(line->Parts[0][0] == ':')    continue;       // Ignore labels
                
                // Prescan and eliminate variables
-               for( j = 1; j < line->nParts; j++ ) {
+               for( j = 1; j < line->nParts; j++ )
+               {
                        Log_Debug("Config", "Arg #%i is '%s'", j, line->Parts[j]);
                        bReplaced[j] = 0;
                        if( line->Parts[j][0] != '$' )  continue;
@@ -278,13 +368,16 @@ void System_ExecuteScript()
                        bReplaced[j] = 1;
                }
                
+               // Find the command name
                for( j = 0; j < NUM_CONFIG_COMMANDS; j++ )
                {
-                       Uint    args[N_MAX_ARGS];
+                       const char      *args[N_MAX_ARGS];
+                       
                        if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0)       continue;
                        
                        Log_Debug("Config", "Command '%s', %i args passed", line->Parts[0], line->nParts-1);
                        
+                       // Check against minimum argument count
                        if( line->nParts - 1 < caConfigCommands[j].MinArgs ) {
                                Log_Warning("Config",
                                        "Configuration command '%s' requires at least %i arguments, %i given",
@@ -293,6 +386,7 @@ void System_ExecuteScript()
                                break;
                        }
                        
+                       // Check for extra arguments
                        if( line->nParts - 1 > caConfigCommands[j].MaxArgs ) {
                                Log_Warning("Config",
                                        "Configuration command '%s' takes at most %i arguments, %i given",
@@ -301,21 +395,50 @@ void System_ExecuteScript()
                                break;
                        }
                        
+                       // Fill in defaults
                        for( k = caConfigCommands[j].MaxArgs-1; k > line->nParts - 1; k-- ) {
                                args[k] = caConfigCommands[j].OptDefaults[k];
                        }
                        
+                       // Convert arguments to integers
                        for( k = line->nParts-1; k--; )
                        {
-                               if( caConfigCommands[j].IntArgs & (1 << k) ) {
-                                       args[k] = atoi(line->Parts[k+1]);
+                               if( k < 32 && (caConfigCommands[j].IntArgs & (1 << k)) ) {
+                                       args[k] = (const char *)(Uint)atoi(line->Parts[k+1]);
                                }
                                else {
-                                       args[k] = (Uint)line->Parts[k+1];
+                                       args[k] = (char *)line->Parts[k+1];
                                }
-                               Log_Debug("Config", "args[%i] = 0x%x", k, args[k]);
+                               Log_Debug("Config", "args[%i] = %p", k, args[k]);
+                       }
+                       switch( (enum eConfigCommands) caConfigCommands[j].Index )
+                       {
+                       case CC_LOADMODULE:
+                               result = Module_LoadFile( args[0], args[1] );
+                               break;
+                       case CC_SPAWN:
+                               result = Proc_Spawn( args[0] );
+                               break;
+                       case CC_MOUNT:
+                               result = VFS_Mount( args[0], args[1], args[2], args[3] );
+                               break;
+                       case CC_SYMLINK:
+                               result = VFS_Symlink( args[0], args[1] );
+                               break;
+                       case CC_OPEN:
+                               result = VFS_Open( args[0], (Uint)args[1] );
+                               break;
+                       case CC_CLOSE:
+                               VFS_Close( (Uint)args[0] );
+                               result = 0;
+                               break;
+                       case CC_MKDIR:
+                               result = VFS_MkDir( args[0] );
+                               break;
+                       case CC_IOCTL:
+                               result = VFS_IOCtl( (Uint)args[0], (Uint)args[1], (void *)args[2] );
+                               break;
                        }
-                       result = CallWithArgArray(caConfigCommands[j].Func, caConfigCommands[j].MaxArgs, args);
                        Log_Debug("Config", "result = %i", result);
                        break;
                }
@@ -415,6 +538,8 @@ void System_ExecuteScript()
                }
                free( file->Lines[i].Parts );
        }
+       
+       // Free data
        free( file );
        free( fData );
 }
@@ -468,6 +593,7 @@ tConfigFile *System_Int_ParseFile(char *FileData)
                start = ptr;
                
                ret->Lines[i].nParts = 0;
+               ret->Lines[i].Parts = NULL;
                
                // Count parts
                for(;;)
@@ -560,6 +686,12 @@ tConfigFile        *System_Int_ParseFile(char *FileData)
                }
        }
        
+       if( i < ret->nLines ) {
+               ret->Lines[i].nParts = 0;
+               ret->Lines[i].Parts = NULL;
+               Log_Log("System", "Cleaning up final empty line");
+       }
+       
        LEAVE('p', ret);
        return ret;
 }

UCC git Repository :: git.ucc.asn.au