Kernel - Integrated PTY with VTerm, userland currently broken
[tpg/acess2.git] / KernelLand / Kernel / system.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  * system.c
5  * - Architecture Independent System Init
6  */
7 #define DEBUG   1
8 #include <acess.h>
9 #include <hal_proc.h>
10
11 // === IMPORTS ===
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
18 // === PROTOTYPES ===
19 void    System_Init(char *Commandline);
20 void    System_ParseCommandLine(char *ArgString);
21 void    System_ExecuteCommandLine(void);
22 void    System_ParseVFS(char *Arg);
23 void    System_ParseModuleArgs(char *Arg);
24 void    System_ParseSetting(char *Arg);
25
26 // === GLOBALS ===
27 const char      *gsInitBinary = "/Acess/SBin/init";
28 char    *argv[32];
29  int    argc;
30
31 // === CODE ===
32 void System_Init(char *CommandLine)
33 {
34         Proc_SpawnWorker(Timer_CallbackThread, NULL);
35
36         // Parse Kernel's Command Line
37         System_ParseCommandLine(CommandLine);
38         
39         // Initialise modules
40         Log_Log("Config", "Initialising builtin modules...");
41         Modules_LoadBuiltins();
42         Arch_LoadBootModules();
43         
44         System_ExecuteCommandLine();
45         
46         // - Execute the Config Script
47         Log_Log("Config", "Spawning init '%s'", gsInitBinary);
48         if(Proc_Clone(CLONE_VM|CLONE_NOUSER) == 0)
49         {
50                 const char      *args[] = {gsInitBinary, 0};
51                 VFS_Open("/Devices/pts/vt0c", VFS_OPENFLAG_READ|VFS_OPENFLAG_USER);     // 0: stdin
52                 VFS_Open("/Devices/pts/vt0c", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER);    // 1: stdout
53                 Proc_Execve(gsInitBinary, args, &args[1], 0);
54                 Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary);
55         }
56         
57         // Set the debug to be echoed to the terminal
58         Log_Log("Config", "Kernel now echoes to VT7 (Ctrl-Alt-F8)");
59         Debug_SetKTerminal("/Devices/pts/vt7c");
60 }
61
62 /**
63  * \fn void System_ParseCommandLine(char *ArgString)
64  * \brief Parses the kernel's command line and sets the environment
65  */
66 void System_ParseCommandLine(char *ArgString)
67 {
68          int    i;
69         char    *str;
70         
71         Log_Log("Config", "Kernel Invocation (%p) \"%s\"", ArgString, ArgString);
72         
73         // --- Get Arguments ---
74         str = ArgString;
75         for( argc = 0; argc < 32; argc++ )
76         {
77                 // Eat Whitespace
78                 while(*str == ' ')      str++;
79                 // Check for the end of the string
80                 if(*str == '\0') {      argc--; break;} 
81                 argv[argc] = str;
82                 if(*str == '"') {
83                         while(*str && !(*str == '"' && str[-1] != '\\'))
84                                 str ++;
85                 }
86                 else {
87                         while(*str && *str != ' ')
88                                 str++;
89                 }
90                 if(*str == '\0')        break;  // Check for EOS
91                 *str = '\0';    // Cap off argument string
92                 str ++; // and increment the string pointer
93         }
94         if(argc < 32)
95                 argc ++;        // Count last argument
96         
97         // --- Parse Arguments (Pass 1) ---
98         for( i = 1; i < argc; i++ )
99         {
100                 switch(argv[i][0])
101                 {
102                 // --- VFS ---
103                 // Ignored on this pass
104                 case '/':
105                         break;
106                 
107                 // --- Module Paramaters ---
108                 // -VTerm:Width=640,Height=480,Scrollback=2
109                 case '-':
110                         System_ParseModuleArgs( argv[i] );
111                         break;
112                 // --- Config Options ---
113                 // SCRIPT=/Acess/Conf/BootConf.cfg
114                 default:
115                         System_ParseSetting( argv[i] );
116                         break;
117                 }
118         }
119 }
120
121 void System_ExecuteCommandLine(void)
122 {
123          int    i;
124         if(argc > 0)
125                 LOG("Invocation '%s'", argv[0]);
126         for( i = 1; i < argc; i++ )
127         {
128                 LOG("argv[%i] = '%s'", i, argv[i]);
129                 switch(argv[i][0])
130                 {
131                 // --- VFS ---
132                 // Mount    /System=ext2:/Devices/ATA/A1
133                 // Symlink  /Acess=/System/Acess2
134                 case '/':
135                         System_ParseVFS( argv[i] );
136                         break;
137                 }
138         }
139 }
140
141 /**
142  * \fn void System_ParseVFS(char *Arg)
143  */
144 void System_ParseVFS(char *Arg)
145 {
146         char    *value;
147          int    fd;
148         
149         value = Arg;
150         // Search for the '=' token
151         while( *value && *value != '=' )
152                 value++;
153         
154         // Check if the equals was found
155         if( *value == '\0' ) {
156                 Log_Warning("Config", "Expected '=' in the string '%s'", Arg);
157                 return ;
158         }
159         
160         // Edit string
161         *value = '\0';  value ++;
162         
163         // Check assignment type
164         // - Symbolic Link <link>=<destination>
165         if(value[0] == '/')
166         {
167 //              Log_Log("Config", "Symbolic link '%s' pointing to '%s'", Arg, value);
168                 VFS_Symlink(Arg, value);
169         }
170         // - Mount <mountpoint>=<fs>:<device>
171         else
172         {
173                 char    *dev = value;
174                 // Find colon
175                 while(*dev && *dev != ':')      dev++;
176                 if(*dev) {
177                         *dev = '\0';
178                         dev++;  // Eat ':'
179                 }
180                 // Create Mountpoint
181                 if( (fd = VFS_Open(Arg, 0)) == -1 ) {
182 //                      Log_Log("Config", "Creating directory '%s'", Arg, value);
183                         VFS_MkDir( Arg );
184                 } else {
185                         VFS_Close(fd);
186                 }
187                 // Mount
188 //              Log_Log("Config", "Mounting '%s' to '%s' ('%s')", dev, Arg, value);
189                 VFS_Mount(dev, Arg, value, "");
190         }
191 }
192
193 /**
194  * \brief Parse a module argument string
195  * \param Arg   Argument string
196  */
197 void System_ParseModuleArgs(char *Arg)
198 {
199         char    *name, *args;
200          int    i;
201         
202         // Remove '-'   
203         name = Arg + 1;
204         
205         // Find the start of the args
206         i = strpos(name, ':');
207         if( i == -1 ) {
208                 Log_Warning("Config", "Module spec with no arguments");
209                 #if 1
210                 return ;
211                 #else
212                 i = strlen(name);
213                 args = name + i;
214                 #endif
215         }
216         else {
217                 name[i] = '\0';
218                 args = name + i + 1;
219         }
220         
221         Log_Log("Config", "Setting boot parameters for '%s' to '%s'", name, args);
222         Modules_SetBuiltinParams(name, args);
223 }
224
225 /**
226  * \fn void System_ParseSetting(char *Arg)
227  */
228 void System_ParseSetting(char *Arg)
229 {
230         char    *value;
231         value = Arg;
232
233         // Search for the '=' token
234         while( *value && *value != '=' )
235                 value++;
236         
237         // Check for boolean/flag (no '=')
238         if(*value == '\0')
239         {
240                 //if(strcmp(Arg, "") == 0) {
241                 //} else {
242                         Log_Warning("Config", "Kernel flag '%s' is not recognised", Arg);
243                 //}
244         }
245         else
246         {
247                 *value = '\0';  // Remove '='
248                 value ++;       // and eat it's position
249                 
250                 if(strcmp(Arg, "INIT") == 0) {
251                         Log_Log("Config", "Init binary: '%s'", value);
252                         if(strlen(value) == 0)
253                                 gsInitBinary = NULL;
254                         else
255                                 gsInitBinary = value;
256                 }
257                 else {
258                         Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
259                 }
260                 
261         }
262 }
263

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