init.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Martin Decky
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <stdio.h>
00038 #include <unistd.h>
00039 #include <vfs/vfs.h>
00040 #include <bool.h>
00041 #include <errno.h>
00042 #include <fcntl.h>
00043 #include <sys/stat.h>
00044 #include <task.h>
00045 #include <malloc.h>
00046 #include <macros.h>
00047 #include <str.h>
00048 #include <devmap.h>
00049 #include <str_error.h>
00050 #include "init.h"
00051 
00052 #define ROOT_DEVICE       "bd/initrd"
00053 #define ROOT_MOUNT_POINT  "/"
00054 
00055 #define DEVFS_FS_TYPE      "devfs"
00056 #define DEVFS_MOUNT_POINT  "/dev"
00057 
00058 #define TMPFS_FS_TYPE      "tmpfs"
00059 #define TMPFS_MOUNT_POINT  "/tmp"
00060 
00061 #define DATA_FS_TYPE      "fat"
00062 #define DATA_DEVICE       "bd/ata1disk0"
00063 #define DATA_MOUNT_POINT  "/data"
00064 
00065 #define SRV_CONSOLE  "/srv/console"
00066 #define APP_GETTERM  "/app/getterm"
00067 
00068 static void info_print(void)
00069 {
00070         printf("%s: HelenOS init\n", NAME);
00071 }
00072 
00073 static bool mount_report(const char *desc, const char *mntpt,
00074     const char *fstype, const char *dev, int rc)
00075 {
00076         switch (rc) {
00077         case EOK:
00078                 if (dev != NULL)
00079                         printf("%s: %s mounted on %s (%s at %s)\n", NAME, desc, mntpt,
00080                             fstype, dev);
00081                 else
00082                         printf("%s: %s mounted on %s (%s)\n", NAME, desc, mntpt, fstype);
00083                 break;
00084         case EBUSY:
00085                 printf("%s: %s already mounted on %s\n", NAME, desc, mntpt);
00086                 return false;
00087         case ELIMIT:
00088                 printf("%s: %s limit exceeded\n", NAME, desc);
00089                 return false;
00090         case ENOENT:
00091                 printf("%s: %s unknown type (%s)\n", NAME, desc, fstype);
00092                 return false;
00093         default:
00094                 printf("%s: %s not mounted on %s (%s)\n", NAME, desc, mntpt,
00095                     str_error(rc));
00096                 return false;
00097         }
00098         
00099         return true;
00100 }
00101 
00102 static bool mount_root(const char *fstype)
00103 {
00104         const char *opts = "";
00105         
00106         if (str_cmp(fstype, "tmpfs") == 0)
00107                 opts = "restore";
00108         
00109         int rc = mount(fstype, ROOT_MOUNT_POINT, ROOT_DEVICE, opts,
00110             IPC_FLAG_BLOCKING);
00111         return mount_report("Root filesystem", ROOT_MOUNT_POINT, fstype,
00112             ROOT_DEVICE, rc);
00113 }
00114 
00115 static bool mount_devfs(void)
00116 {
00117         int rc = mount(DEVFS_FS_TYPE, DEVFS_MOUNT_POINT, "", "",
00118             IPC_FLAG_BLOCKING);
00119         return mount_report("Device filesystem", DEVFS_MOUNT_POINT, DEVFS_FS_TYPE,
00120             NULL, rc);
00121 }
00122 
00123 static void spawn(const char *fname)
00124 {
00125         int rc;
00126         struct stat s;
00127         
00128         if (stat(fname, &s) == ENOENT)
00129                 return;
00130         
00131         printf("%s: Spawning %s\n", NAME, fname);
00132         rc = task_spawnl(NULL, fname, fname, NULL);
00133         if (rc != EOK) {
00134                 printf("%s: Error spawning %s (%s)\n", NAME, fname,
00135                     str_error(rc));
00136         }
00137 }
00138 
00139 static void srv_start(const char *fname)
00140 {
00141         task_id_t id;
00142         task_exit_t texit;
00143         int rc, retval;
00144         struct stat s;
00145         
00146         if (stat(fname, &s) == ENOENT)
00147                 return;
00148         
00149         printf("%s: Starting %s\n", NAME, fname);
00150         rc = task_spawnl(&id, fname, fname, NULL);
00151         if (!id) {
00152                 printf("%s: Error spawning %s (%s)\n", NAME, fname,
00153                     str_error(rc));
00154                 return;
00155         }
00156         
00157         rc = task_wait(id, &texit, &retval);
00158         if (rc != EOK) {
00159                 printf("%s: Error waiting for %s (%s(\n", NAME, fname,
00160                     str_error(rc));
00161                 return;
00162         }
00163         
00164         if (texit != TASK_EXIT_NORMAL) {
00165                 printf("%s: Server %s failed to start (unexpectedly "
00166                     "terminated)\n", NAME, fname);
00167                 return;
00168         }
00169 
00170         if (retval != 0) {
00171                 printf("%s: Server %s failed to start (exit code %d)\n", NAME,
00172                         fname, retval);
00173         }
00174 }
00175 
00176 static void console(const char *dev)
00177 {
00178         char hid_in[DEVMAP_NAME_MAXLEN];
00179         int rc;
00180         
00181         snprintf(hid_in, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
00182         
00183         printf("%s: Spawning %s %s\n", NAME, SRV_CONSOLE, hid_in);
00184         
00185         /* Wait for the input device to be ready */
00186         devmap_handle_t handle;
00187         rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
00188         if (rc != EOK) {
00189                 printf("%s: Error waiting on %s (%s)\n", NAME, hid_in,
00190                     str_error(rc));
00191                 return;
00192         }
00193         
00194         rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, hid_in, NULL);
00195         if (rc != EOK) {
00196                 printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE,
00197                     hid_in, str_error(rc));
00198         }
00199 }
00200 
00201 static void getterm(const char *dev, const char *app, bool wmsg)
00202 {
00203         char term[DEVMAP_NAME_MAXLEN];
00204         int rc;
00205         
00206         snprintf(term, DEVMAP_NAME_MAXLEN, "%s/%s", DEVFS_MOUNT_POINT, dev);
00207         
00208         printf("%s: Spawning %s %s %s\n", NAME, APP_GETTERM, term, app);
00209         
00210         /* Wait for the terminal device to be ready */
00211         devmap_handle_t handle;
00212         rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
00213         if (rc != EOK) {
00214                 printf("%s: Error waiting on %s (%s)\n", NAME, term,
00215                     str_error(rc));
00216                 return;
00217         }
00218         
00219         if (wmsg) {
00220                 rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, "-w", term,
00221                     app, NULL);
00222                 if (rc != EOK) {
00223                         printf("%s: Error spawning %s -w %s %s (%s)\n", NAME,
00224                             APP_GETTERM, term, app, str_error(rc));
00225                 }
00226         } else {
00227                 rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, term, app,
00228                     NULL);
00229                 if (rc != EOK) {
00230                         printf("%s: Error spawning %s %s %s (%s)\n", NAME,
00231                             APP_GETTERM, term, app, str_error(rc));
00232                 }
00233         }
00234 }
00235 
00236 static bool mount_tmpfs(void)
00237 {
00238         int rc = mount(TMPFS_FS_TYPE, TMPFS_MOUNT_POINT, "", "", 0);
00239         return mount_report("Temporary filesystem", TMPFS_MOUNT_POINT,
00240             TMPFS_FS_TYPE, NULL, rc);
00241 }
00242 
00243 static bool mount_data(void)
00244 {
00245         int rc = mount(DATA_FS_TYPE, DATA_MOUNT_POINT, DATA_DEVICE, "wtcache", 0);
00246         return mount_report("Data filesystem", DATA_MOUNT_POINT, DATA_FS_TYPE,
00247             DATA_DEVICE, rc);
00248 }
00249 
00250 int main(int argc, char *argv[])
00251 {
00252         info_print();
00253         
00254         if (!mount_root(STRING(RDFMT))) {
00255                 printf("%s: Exiting\n", NAME);
00256                 return -1;
00257         }
00258         
00259         /* Make sure tmpfs is running. */
00260         if (str_cmp(STRING(RDFMT), "tmpfs") != 0) {
00261                 spawn("/srv/tmpfs");
00262         }
00263         
00264         spawn("/srv/devfs");
00265         spawn("/srv/taskmon");
00266         
00267         if (!mount_devfs()) {
00268                 printf("%s: Exiting\n", NAME);
00269                 return -2;
00270         }
00271         
00272         mount_tmpfs();
00273         
00274         spawn("/srv/apic");
00275         spawn("/srv/i8259");
00276         spawn("/srv/fhc");
00277         spawn("/srv/obio");
00278         srv_start("/srv/cuda_adb");
00279         srv_start("/srv/i8042");
00280         srv_start("/srv/s3c24ser");
00281         srv_start("/srv/adb_ms");
00282         srv_start("/srv/char_ms");
00283         srv_start("/srv/s3c24ts");
00284         
00285         spawn("/srv/fb");
00286         spawn("/srv/kbd");
00287         console("hid_in/kbd");
00288         
00289         spawn("/srv/clip");
00290         
00291         /*
00292          * Start these synchronously so that mount_data() can be
00293          * non-blocking.
00294          */
00295 #ifdef CONFIG_START_BD
00296         srv_start("/srv/ata_bd");
00297         srv_start("/srv/gxe_bd");
00298 #else
00299         (void) srv_start;
00300 #endif
00301         
00302 #ifdef CONFIG_MOUNT_DATA
00303         mount_data();
00304 #else
00305         (void) mount_data;
00306 #endif
00307         
00308         getterm("term/vc0", "/app/bdsh", true);
00309         getterm("term/vc1", "/app/bdsh", false);
00310         getterm("term/vc2", "/app/bdsh", false);
00311         getterm("term/vc3", "/app/bdsh", false);
00312         getterm("term/vc4", "/app/bdsh", false);
00313         getterm("term/vc5", "/app/bdsh", false);
00314         getterm("term/vc6", "/app/klog", false);
00315 
00316 #ifdef CONFIG_START_DEVMAN
00317 
00318 #ifdef CONFIG_DEVMAN_EARLY_LAUNCH
00319         spawn("/srv/devman");
00320 #else
00321         getterm("term/vc7", "/srv/devman", false);
00322 #endif
00323 
00324 #endif
00325 
00326         return 0;
00327 }
00328 

Generated on Thu Jun 2 07:45:41 2011 for HelenOS/USB by  doxygen 1.4.7