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

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