00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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
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
00293
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