version 1.1.1.1, 2008/06/03 10:38:51 |
version 1.1.1.1.2.1, 2008/08/13 17:12:43 |
|
|
*/ |
*/ |
|
|
/* |
/* |
* A bootstrap server works to setup the POSIX environment for 'init' |
* A bootstrap server works to setup the POSIX environment for |
* process. It sends a setup message to other servers in order to let |
* 'init' process. It sends a setup message to other servers in |
* them know that this task becomes 'init' process. |
* order to let them know that this task becomes 'init' process. |
* The bootstrap server is gone after it launches (exec) the 'init' |
* The bootstrap server is gone after it launches (exec) the |
* process. |
* 'init' process. |
*/ |
*/ |
|
|
#include <prex/prex.h> |
#include <prex/prex.h> |
|
|
#include <errno.h> |
#include <errno.h> |
#include <fstab.h> |
#include <fstab.h> |
|
|
|
#ifdef DEBUG |
|
#define DPRINTF(a) sys_log a |
|
#else |
|
#define DPRINTF(a) |
|
#endif |
|
|
extern const struct fstab fstab[]; |
extern const struct fstab fstab[]; |
extern const int fstab_size; |
extern const int fstab_size; |
|
|
#define PRIO_BOOT 131 /* priority of boot server */ |
#define PRIO_BOOT 131 /* priority of boot server */ |
|
|
/* forward declarations */ |
/* forward declarations */ |
static void wait_server(const char *); |
static void wait_server(const char *); |
static void process_init(void); |
static void process_init(void); |
static int run_init(char *); |
static int run_init(char *); |
static void mount_fs(void); |
static void mount_fs(void); |
|
|
static object_t proc_obj; |
static object_t proc_obj; |
|
|
static char *init_argv[] = { "arg", NULL }; |
static char *init_argv[] = { "arg", NULL }; |
static char *init_envp[] = { "HOME=/", NULL }; |
static char *init_envp[] = { "HOME=/", NULL }; |
|
|
|
/* |
|
* Base directories |
|
*/ |
static char *base_dir[] = { |
static char *base_dir[] = { |
"/bin", /* essential user commands */ |
"/bin", /* essential user commands */ |
"/boot", /* static files for boot */ |
"/boot", /* static files for boot */ |
|
|
"/mnt", /* mount point for file systems */ |
"/mnt", /* mount point for file systems */ |
"/mnt/floppy", /* mount point for floppy */ |
"/mnt/floppy", /* mount point for floppy */ |
"/mnt/cdrom", /* mount point for cdrom */ |
"/mnt/cdrom", /* mount point for cdrom */ |
|
"/fifo", /* mount point for fifo */ |
"/tmp", /* temporary files */ |
"/tmp", /* temporary files */ |
"/usr", /* shareable read-only data */ |
"/usr", /* shareable read-only data */ |
"/var", /* log files, spool data */ |
"/var", /* log files, spool data */ |
|
|
}; |
}; |
|
|
/* |
/* |
* Main routine for boot strap |
* Main routine for boot strap. |
*/ |
*/ |
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
|
|
thread_setprio(thread_self(), PRIO_BOOT); |
thread_setprio(thread_self(), PRIO_BOOT); |
|
|
/* |
/* |
* Wait until required system servers become available. |
* Wait until required system servers |
|
* become available. |
*/ |
*/ |
wait_server(OBJNAME_PROC); |
wait_server(OBJNAME_PROC); |
wait_server(OBJNAME_FS); |
wait_server(OBJNAME_FS); |
|
|
*/ |
*/ |
run_init("/boot/init"); |
run_init("/boot/init"); |
|
|
sys_log("boot: failed to run init\n"); |
sys_panic("boot: failed to run init"); |
|
/* NOTREACHED */ |
return 0; |
return 0; |
} |
} |
|
|
|
|
sys_panic("boot: server not found"); |
sys_panic("boot: server not found"); |
} |
} |
|
|
|
/* |
|
* Notify the process server. |
|
*/ |
static void |
static void |
process_init(void) |
process_init(void) |
{ |
{ |
struct msg m; |
struct msg m; |
|
|
/* |
/* |
* This task will become an init process. |
* We will become an init process later. |
*/ |
*/ |
object_lookup(OBJNAME_PROC, &proc_obj); |
object_lookup(OBJNAME_PROC, &proc_obj); |
m.hdr.code = PS_SETINIT; |
m.hdr.code = PS_SETINIT; |
|
|
char *dest, *src; |
char *dest, *src; |
object_t obj; |
object_t obj; |
|
|
sys_log("boot: Run init process\n"); |
DPRINTF(("boot: Run init process\n")); |
|
|
/* |
/* |
* Allocate a message buffer with arg/env data. |
* Allocate a message buffer with arg/env data. |
*/ |
*/ |
bufsz = 0; |
bufsz = 0; |
argc = 0; |
argc = 0; |
while (init_argv[argc]) { |
while (init_argv[argc] != NULL) { |
bufsz += (strlen(init_argv[argc]) + 1); |
bufsz += (strlen(init_argv[argc]) + 1); |
argc++; |
argc++; |
} |
} |
envc = 0; |
envc = 0; |
while (init_envp[envc]) { |
while (init_envp[envc] != NULL) { |
bufsz += (strlen(init_envp[envc]) + 1); |
bufsz += (strlen(init_envp[envc]) + 1); |
envc++; |
envc++; |
} |
} |
msg = (struct exec_msg *)malloc(sizeof(struct exec_msg) + bufsz); |
msg = malloc(sizeof(struct exec_msg) + bufsz); |
if (msg == NULL) |
if (msg == NULL) |
return -1; |
return -1; |
|
|
|
|
err = msg_send(obj, msg, |
err = msg_send(obj, msg, |
sizeof(struct exec_msg) + bufsz); |
sizeof(struct exec_msg) + bufsz); |
/* |
/* |
* If exec server can execute new process properly, it |
* If exec server can execute new process |
* will terminate the caller task automatically. So, |
* properly, it will terminate the caller task |
* the control never comes here in that case. |
* automatically. So, the control never comes |
|
* here in that case. |
*/ |
*/ |
} while (err == EINTR); |
} while (err == EINTR); |
return -1; |
return -1; |
|
|
{ |
{ |
int i; |
int i; |
|
|
sys_log("boot: Mounting file systems\n"); |
DPRINTF(("boot: Mounting file systems\n")); |
|
|
/* |
/* |
* Mount RAMFS as root file system. |
* Mount RAMFS as root file system. |
|
|
/* |
/* |
* Create some default directories on RAMFS. |
* Create some default directories on RAMFS. |
*/ |
*/ |
for (i = 0;; i++) { |
i = 0; |
if (base_dir[i] == NULL) |
while (base_dir[i] != NULL) { |
break; |
|
mkdir(base_dir[i], 0); |
mkdir(base_dir[i], 0); |
|
i++; |
} |
} |
|
|
/* |
/* |