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

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