openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

init.c (7143B)


      1 /* $Id: //depot/blt/srv/init/init.c#11 $
      2 **
      3 ** Copyright 1999 Sidney Cammeresi
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 /*
     30  * Since nothing is running yet, we divide the system startup into two
     31  * phases:  starting bootstrap servers and normal initialisation.  The
     32  * former requires lots of strange incantations to parse the boot image
     33  * to find rc.boot and run everything it says to; basically we have to
     34  * reimplement what execve and the vfs do for us.  Once that stuff gets
     35  * going, we can open rc using the vfs and proceed in a more normal
     36  * fashion.
     37  *
     38  * As rc.boot contains fairly critical stuff, an error from something
     39  * in there will probably result in a wedged system.
     40  *
     41  * Microkernels are fun.
     42  *
     43  *         - sc
     44  */
     45 
     46 #include <stdio.h>
     47 #include <stdlib.h>
     48 #include <string.h>
     49 #include <fcntl.h>
     50 #include <errno.h>
     51 #include <unistd.h>
     52 #include <boot.h>
     53 #include <blt/syscall.h>
     54 
     55 static char *copyright = "\
     56 OpenBLT Release I (built " __DATE__ ", " __TIME__ ")
     57     Copyright (c) 1998-1999 The OpenBLT Dev Team.  All rights reserved.
     58 \n";
     59 
     60 void __libc_init_fdl (void), __libc_init_console (void),
     61 	__libc_init_vfs (void);
     62 
     63 int boot_get_num (boot_dir *dir, const char *name)
     64 {
     65 	int i;
     66 
     67 	for (i = 0; i < BOOTDIR_MAX_ENTRIES; i++)
     68 		if (!strcmp (dir->bd_entry[i].be_name, name))
     69 			return i;
     70 	return -1;
     71 }
     72 
     73 char *boot_get_data (boot_dir *dir, int num)
     74 {
     75 	return (char *) dir + dir->bd_entry[num].be_offset * 0x1000;
     76 }
     77 
     78 int main (void)
     79 {
     80 	int area, sarea;
     81 	char *c, *rcboot, *line, *boot_servers, **params;
     82 	int i, space, p_argc, boot, fd, len, total, prog, filenum;
     83 	void *ptr;
     84 	boot_dir *dir;
     85 
     86 	
     87 	line = malloc (256);
     88 	boot_servers = malloc (256);
     89 
     90 	if (!(boot = area_clone (3, 0, (void **) &dir, 0)))
     91 	{
     92 		os_console ("no uberarea; giving up");
     93 		os_debug ();
     94 		for (;;) ; /* fatal */
     95 		return 0;
     96 	}
     97 	else if ((filenum = boot_get_num (dir, "rc.boot")) < 0)
     98 	{
     99 		os_console ("no /boot/rc.boot; do you know what you're doing?");
    100 		os_debug ();
    101 	}
    102 	else
    103 	{
    104         *line = *boot_servers = len = total = 0;
    105 		rcboot = boot_get_data (dir, filenum);
    106 
    107         while (total < dir->bd_entry[filenum].be_vsize)
    108         {
    109 			line[len++] = *rcboot++;
    110 			total++;
    111 
    112             if (line[len - 1] == '\n')
    113             {   
    114                 line[len-- - 1] = 0;
    115                 for (i = space = 0, p_argc = 2; i < len; i++)
    116                     if ((line[i] == ' ') && !space)
    117                         space = 1;
    118                     else if ((line[i] != ' ') && space)
    119                     {   
    120                         p_argc++;
    121                         space = 0;
    122                     }
    123                 if ((*line != '#') && *line)
    124                 {
    125                     params = malloc (sizeof (char *) * p_argc);
    126                     c = line;
    127                     for (i = 0; i < p_argc - 1; i++)
    128                     {
    129                         for (len = 0; c[len] && (c[len] != ' '); len++) ;
    130                         params[i] = malloc (len + 1);
    131                         strlcpy (params[i], c, len + 1);
    132                         c += len + 1;
    133                     }
    134                     params[i] = NULL;
    135                     if (!strcmp (params[0], "exit"))
    136                         os_terminate (1);
    137 
    138 					prog = boot_get_num (dir, params[0]);
    139 					area = area_create (dir->bd_entry[prog].be_vsize, 0,
    140 						&ptr, 0);
    141 					memcpy (ptr, boot_get_data (dir, prog),
    142 						dir->bd_entry[prog].be_vsize);
    143 					sarea = area_create (0x1000, 0, &ptr, 0);
    144 					strlcat (boot_servers, " ", 256);
    145 					strlcat (boot_servers, params[0], 256);
    146 					thr_wait (thr_spawn (0x1074, 0x3ffffd, area, 0x1000,
    147 						sarea, 0x3ff000, params[0]));
    148                 }
    149                 len = 0;
    150             }
    151         }
    152 	}
    153 
    154 	/* say hello */
    155 	__libc_init_fdl ();
    156 	__libc_init_console ();
    157 	__libc_init_vfs ();
    158 	printf (copyright);
    159 	printf ("init: bootstrap servers started.  [ %s ]\n", boot_servers + 1);
    160 
    161 	/* if we one day pass arguments to init, we will parse them here. */
    162 
    163 	/* do some more normal stuff */
    164 	printf ("init: beginning automatic boot.\n\n");
    165 	fd = open ("/boot/rc", O_RDONLY, 0);
    166 	if (fd < 0)
    167 		printf ("error opening /boot/rc\n");
    168 	else
    169 	{
    170 		*line = len = 0;
    171 		while (read (fd, line + len++, 1) > 0)
    172 		{
    173 			if (line[len - 1] == '\n')
    174 			{
    175 /*
    176 				line[len - 1] = 0;
    177 				if ((*line != '#') && *line)
    178 				{
    179 					// printf ("execing `%s'\n", line);
    180 					params = malloc (sizeof (char *) * 2);
    181 					params[0] = malloc (strlen (line) + 1);
    182 					strcpy (params[0], line);
    183 					params[1] = NULL;
    184 					thr_join (thr_detach (run2), 0);
    185 				}
    186 				len = 0;
    187 */
    188                 line[len-- - 1] = 0;
    189                 for (i = space = 0, p_argc = 2; i < len; i++)
    190                     if ((line[i] == ' ') && !space)
    191                         space = 1;
    192                     else if ((line[i] != ' ') && space)
    193                     {   
    194                         p_argc++;
    195                         space = 0;
    196                     }
    197                 if ((*line != '#') && *line)
    198                 {
    199                     params = malloc (sizeof (char *) * p_argc);
    200                     c = line;
    201                     for (i = 0; i < p_argc - 1; i++)
    202                     {
    203                         for (len = 0; c[len] && (c[len] != ' '); len++) ;
    204                         params[i] = malloc (len + 1);
    205                         strlcpy (params[i], c, len + 1);
    206                         c += len + 1;
    207                     }
    208                     params[i] = NULL;
    209                     if (!strcmp (params[0], "exit"))
    210                         os_terminate (1);
    211 						
    212 					i = execve (params[0], params, NULL);
    213 					if(i>0) thr_wait(i);
    214 					else printf("cannot execute \"%s\"\n",params[0]);
    215                 }
    216                 len = 0;
    217 			}
    218 		}
    219 		close (fd);
    220 	}
    221 
    222 	printf ("init: nothing left to do\n");
    223 	return 0;
    224 }
    225