X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fsystem.c;fp=KernelLand%2FKernel%2Fsystem.c;h=8fc2a1ccea4f8e7348f0a44d9c9bb909452da3fd;hb=48743e39650eb1ef988380e9d95f27fd40d3a9ce;hp=0000000000000000000000000000000000000000;hpb=a2495c6ea4f4cab16b5d339ae511428e92e89e73;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/system.c b/KernelLand/Kernel/system.c new file mode 100644 index 00000000..8fc2a1cc --- /dev/null +++ b/KernelLand/Kernel/system.c @@ -0,0 +1,252 @@ +/* + * Acess 2 Kernel + * - By John Hodge (thePowersGang) + * system.c + * - Architecture Independent System Init + */ +#define DEBUG 0 +#include + +// === 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 = + if(value[0] == '/') + { + Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value); + VFS_Symlink(Arg, value); + } + // - Mount =: + 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); + } + + } +} +