Actually initialised the DMA
[tpg/acess2.git] / Kernel / system.c
1 /*
2  * Acess 2
3  * Architecture Independent System Init
4  * system.c
5  */
6 #include <common.h>
7
8 // === IMPORTS ===
9 extern int      Modules_LoadBuiltins();
10 extern int      PCI_Install();
11 extern void     DMA_Install();
12
13 // === PROTOTYPES ===
14 void    System_Init(char *ArgString);
15 void    System_ParseCommandLine(char *ArgString);
16 void    System_ParseVFS(char *Arg);
17 void    System_ParseSetting(char *Arg);
18 void    System_ExecuteScript();
19  int    System_Int_GetString(char *Str, char **Dest);
20
21 // === GLOBALS ===
22 char    *gsInitPath = "/Acess/Bin/init";
23 char    *gsConfigScript = "/Acess/Conf/BootConf.cfg";
24
25 // === CODE ===
26 void System_Init(char *ArgString)
27 {
28         // - Start Builtin Drivers & Filesystems
29         PCI_Install();
30         DMA_Install();
31         Modules_LoadBuiltins();
32         
33         // - Parse Kernel's Command Line
34         System_ParseCommandLine(ArgString);
35         
36         // - Execute the Config Script
37         Log("Executing config script...");
38         System_ExecuteScript();
39 }
40
41 /**
42  * \fn void System_ParseCommandLine(char *ArgString)
43  * \brief Parses the kernel's command line and sets the environment
44  */
45 void System_ParseCommandLine(char *ArgString)
46 {
47         char    *argv[32];
48          int    argc;
49          int    i;
50         char    *str;
51         
52         Log("Kernel Command Line: \"%s\"", ArgString);
53         
54         // --- Get Arguments ---
55         str = ArgString;
56         for( argc = 0; argc < 32; argc++ )
57         {
58                 while(*str == ' ')      str++;  // Eat Whitespace
59                 if(*str == '\0') {      argc--; break;} // End of string
60                 argv[argc] = str;
61                 while(*str && *str != ' ')
62                 {
63                         /*if(*str == '"') {
64                                 while(*str && !(*str == '"' && str[-1] != '\\'))
65                                         str ++;
66                         }*/
67                         str++;
68                 }
69                 if(*str == '\0')        break;  // End of string
70                 *str = '\0';    // Cap off argument string
71                 str ++; // and increment the string pointer
72         }
73         if(argc < 32)
74                 argc ++;        // Count last argument
75         
76         // --- Parse Arguments ---
77         for( i = 1; i < argc; i++ )
78         {
79                 if( argv[i][0] == '/' )
80                         System_ParseVFS( argv[i] );
81                 else
82                         System_ParseSetting( argv[i] );
83         }
84 }
85
86 /**
87  * \fn void System_ParseVFS(char *Arg)
88  */
89 void System_ParseVFS(char *Arg)
90 {
91         char    *value;
92          int    fd;
93         
94         value = Arg;
95         // Search for the '=' token
96         while( *value && *value != '=' )
97                 value++;
98         
99         // Check if the equals was found
100         if( *value == '\0' ) {
101                 Warning("Expected '=' in the string '%s'", Arg);
102                 return ;
103         }
104         
105         // Edit string
106         *value = '\0';  value ++;
107         
108         // Check assignment type
109         // - Symbolic Link <link>=<destination>
110         if(value[0] == '/')
111         {
112                 Log("Symbolic link '%s' pointing to '%s'", Arg, value);
113                 VFS_Symlink(Arg, value);
114         }
115         // - Mount <mountpoint>=<fs>:<device>
116         else
117         {
118                 char    *dev = value;
119                 // Find colon
120                 while(*dev && *dev != ':')      dev++;
121                 if(*dev) {
122                         *dev = '\0';
123                         dev++;  // Eat ':'
124                 }
125                 // Create Mountpoint
126                 if( (fd = VFS_Open(Arg, 0)) == -1 ) {
127                         Log("Creating directory '%s'", Arg, value);
128                         VFS_MkDir( Arg );
129                 } else {
130                         VFS_Close(fd);
131                 }
132                 // Mount
133                 Log("Mounting '%s' to '%s' ('%s')", dev, Arg, value);
134                 VFS_Mount(dev, Arg, value, "");
135         }
136 }
137
138 /**
139  * \fn void System_ParseSetting(char *Arg)
140  */
141 void System_ParseSetting(char *Arg)
142 {
143         char    *value;
144         value = Arg;
145
146         // Search for the '=' token
147         while( *value && *value != '=' )
148                 value++;
149         
150         // Check for boolean/flag (no '=')
151         if(*value == '\0')
152         {
153                 if(strcmp(Arg, "") == 0) {
154                 } else {
155                         Warning("Kernel flag '%s' is not recognised", Arg);
156                 }
157         }
158         else
159         {
160                 *value = '\0';  // Remove '='
161                 value ++;       // and eat it's position
162                 
163                 if(strcmp(Arg, "SCRIPT") == 0) {
164                         Log("Config Script: '%s'", value);
165                         gsConfigScript = value;
166                 } else {
167                         Warning("Kernel config setting '%s' is not recognised", Arg);
168                 }
169                 
170         }
171 }
172
173 /**
174  * \fn void System_ExecuteScript()
175  */
176 void System_ExecuteScript()
177 {
178          int    fp;
179          int    fLen = 0;
180          int    i = 0, lineStart;
181         char    *sArg1, *sArg2, *sArg3;
182         char    *fData;
183         
184         // Open Script
185         fp = VFS_Open(gsConfigScript, VFS_OPENFLAG_READ);
186         if(fp == -1) {
187                 Warning("[CFG] Passed script '%s' does not exist", gsConfigScript);
188                 return;
189         }
190         
191         // Read into memory buffer
192         VFS_Seek(fp, 0, SEEK_END);
193         fLen = VFS_Tell(fp);
194         VFS_Seek(fp, 0, SEEK_SET);
195         fData = malloc(fLen+1);
196         VFS_Read(fp, fLen, fData);
197         fData[fLen] = '\0';
198         VFS_Close(fp);
199         
200         // Read Script
201         while(i < fLen)
202         {
203                 sArg1 = sArg2 = sArg3 = NULL;
204                 
205                 lineStart = i;
206                 // Clear leading whitespace and find empty lines
207                 while(i < fLen && (fData[i] == ' ' || fData[i]=='\t'))  i ++;
208                 if(i == fLen)   break;
209                 if(fData[i] == '\n') {
210                         i++;
211                         continue;
212                 }
213                 
214                 // Comment
215                 if(fData[i] == ';' || fData[i] == '#') {
216                         while(i < fLen && fData[i] != '\n')     i ++;
217                         i ++;
218                         continue;
219                 }
220                 
221                 // Commands
222                 // - Mount
223                 if(strncmp("mount ", fData+i, 6) == 0) {
224                         i += 6;
225                         i += System_Int_GetString(fData+i, &sArg1);
226                         if(!sArg1)      goto read2eol;
227                         i += System_Int_GetString(fData+i, &sArg2);
228                         if(!sArg2)      goto read2eol;
229                         i += System_Int_GetString(fData+i, &sArg3);
230                         if(!sArg3)      goto read2eol;
231                         //Log("[CFG ] Mount '%s' to '%s' (%s)\n", sArg1, sArg2, sArg3);
232                         VFS_Mount(sArg1, sArg2, sArg3, "");
233                 }
234                 // - Load Module
235                 else if(strncmp("module ", fData+i, 6) == 0) {
236                         i += 7;
237                         i += System_Int_GetString(fData+i, &sArg1);
238                         if(!sArg1)      goto read2eol;
239                         //Log("[CFG ] Load Module '%s'\n", sArg1);
240                         Module_LoadFile(sArg1, "");     //!\todo Use the rest of the line as the argument string
241                 }
242                 // - Load Module
243                 else if(strncmp("edimod ", fData+i, 6) == 0) {
244                         i += 7;
245                         i += System_Int_GetString(fData+i, &sArg1);
246                         if(!sArg1)      goto read2eol;
247                         Log("[CFG ] Load EDI Module '%s'\n", sArg1);
248                         Module_LoadFile(sArg1, "");
249                 }
250                 // - Symlink
251                 else if(strncmp("symlink ", fData+i, 7) == 0) {
252                         i += 8;
253                         i += System_Int_GetString(fData+i, &sArg1);
254                         if(!sArg1)      goto read2eol;
255                         i += System_Int_GetString(fData+i, &sArg2);
256                         if(!sArg2)      goto read2eol;
257                         Log("[CFG ] Symlink '%s' pointing to '%s'\n", sArg1, sArg2);
258                         VFS_Symlink(sArg1, sArg2);
259                 }
260                 // - New Directory
261                 else if(strncmp("mkdir ", fData+i, 5) == 0) {
262                         i += 6;
263                         i += System_Int_GetString(fData+i, &sArg1);
264                         if(!sArg1)      goto read2eol;
265                         Log("[CFG ] New Directory '%s'\n", sArg1);
266                         VFS_MkDir(sArg1);
267                 }
268                 // - Spawn a task
269                 else if(strncmp("spawn ", fData+i, 5) == 0) {
270                         i += 6;
271                         i += System_Int_GetString(fData+i, &sArg1);
272                         if(!sArg1)      goto read2eol;
273                         Log("[CFG ] Starting '%s' as a new task\n", sArg1);
274                         Proc_Spawn(sArg1);
275                 }
276                 else {
277                         Warning("Unknown configuration command, Line: '%s'", fData+i);
278                         goto read2eol;
279                 }
280         read2eol:
281                 if(sArg1)       free(sArg1);
282                 if(sArg2)       free(sArg2);
283                 if(sArg3)       free(sArg3);
284                 // Skip to EOL
285                 while(i < fLen && fData[i] != '\n')     i++;
286                 i ++;   // Skip \n
287         }
288         free(fData);
289 }
290
291 /**
292  * \fn int System_Int_GetString(char *Str, char **Dest)
293  * \brief Gets a string from another
294  * \note Destructive
295  * \param Str   Input String
296  * \param Dest  Pointer to output pointer
297  * \return Characters eaten from input
298  */
299 int System_Int_GetString(char *Str, char **Dest)
300 {
301          int    pos = 0;
302          int    start = 0;
303          int    len;
304          
305         //LogF("GetString: (Str='%s', Dest=0x%x)\n", Str, Dest);
306          
307         while(Str[pos] == ' ' || Str[pos] == '\t')      pos++;
308         if(Str[pos] == '\n' || Str[pos] == '\0') {
309                 *Dest = NULL;
310                 return pos;
311         }
312         
313         // Quoted String
314         if(Str[pos] == '"')
315         {
316                 pos ++;
317                 start = pos;
318                 while(Str[pos] != '"')  pos++;
319                 
320                 len = pos - start;
321                 *Dest = malloc( len + 1 );
322                 memcpy( *Dest, Str+start, len );
323                 (*Dest)[len] = '\0';
324                 
325                 //LogF("GetString: RETURN *Dest = '%s'\n", *Dest);
326                 
327                 pos++;
328                 return pos;
329         }
330         
331         // Non-Quoted String - Whitespace deliminated
332         start = pos;
333         while(Str[pos] != ' ' && Str[pos] != '\t' && Str[pos] != '\n')  pos++;
334         
335         len = pos - start;
336         //LogF(" GetString: len = %i\n", len);
337         *Dest = malloc( len + 1 );
338         memcpy( *Dest, Str+start, len );
339         (*Dest)[len] = '\0';
340         
341         //LogF("GetString: RETURN *Dest = '%s'\n", *Dest);
342         
343         return pos;
344 }

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