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