1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
/*
* Copyright (c) 1997-1999 University of Utah and the Flux Group.
* All rights reserved.
*
* This file is part of the Flux OSKit. The OSKit is free software, also known
* as "open source;" you can redistribute it and/or modify it under the terms
* of the GNU General Public License (GPL), version 2, as published by the Free
* Software Foundation (FSF). To explore alternate licensing terms, contact
* the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
*
* The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have
* received a copy of the GPL along with the OSKit; see the file COPYING. If
* not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
*/
/*
* Convenience function to start up clock, disk filesystem, swap, and network.
*/
#include <oskit/startup.h>
#include <oskit/c/stdio.h>
#include <oskit/c/stdlib.h>
#include <oskit/c/string.h>
#include <oskit/c/unistd.h>
#include <oskit/c/sys/types.h>
#include <oskit/c/sys/stat.h>
#include <oskit/c/ctype.h>
#include <oskit/io/absio.h>
#include <oskit/io/blkio.h>
#include <oskit/c/fs.h>
#include <oskit/fs/memfs.h>
#include <oskit/svm.h>
#include <oskit/clientos.h>
#include <oskit/com/libcenv.h>
#ifdef PTHREADS
#include <oskit/threads/pthread.h>
#define start_world start_world_pthreads
#define start_console start_console_pthreads
#define start_network start_network_pthreads
#define start_fs start_fs_pthreads
#define start_fs_on_blkio start_fs_on_blkio_pthreads
#define start_fs_bmod start_fs_bmod_pthreads
#define start_svm start_svm_pthreads
#define start_svm_on_blkio start_svm_on_blkio_pthreads
#endif
static int disk_option(const char *option, const char *ro_option,
oskit_blkio_t **out_bio);
void
start_world(void)
{
oskit_blkio_t *bio;
oskit_error_t rc;
static int run;
if (run)
return;
run = 1;
/*
* Initialize the startup library atexit code.
*/
startup_atexit_init();
/*
* Start the system clock.
*/
start_clock();
#ifdef PTHREADS
start_pthreads();
#else
#define osenv_process_lock() ((void)0)
#define osenv_process_unlock() ((void)0)
#endif
/*
* Initialize and probe device drivers.
*/
osenv_process_lock();
start_devices();
osenv_process_unlock();
/*
* If we have a "root=device" argument, start the disk filesystem.
*/
if (disk_option("root", "read-only", &bio)) {
start_fs_on_blkio(bio);
if (getenv("no-bmod"))
goto skipbmod;
/*
* Mount the bmod also, in a well-known place.
*/
if (mkdir("/bmod", 0) < 0 && errno != EEXIST) {
perror("start_world: Could not mkdir /bmod\n");
goto skipbmod;
}
if ((rc = fs_mount("/bmod",
(oskit_file_t *) start_bmod())) != 0)
printf("start_world: fs_mount failed\n");
skipbmod:
}
else {
/*
* Otherwise just set up the bmod filesystem.
*/
start_fs_bmod();
/*
* Create its well-known name.
*/
if (symlink("/", "/bmod") < 0)
perror("start_world: Could not symlink /bmod --> /\n");
}
/*
* If we have a "swap=device" argument, start paging to that disk.
*/
if (disk_option("swap", 0, &bio)) {
start_svm_on_blkio((oskit_blkio_t *) bio);
/*
* Don't need the partition anymore, SVM has a ref.
*/
oskit_blkio_release(bio);
}
else if (!getenv("no-svm")) {
/*
* Otherwise, no paging.
*/
start_svm((char *) NULL, (char *) NULL);
}
/*
* Start the network.
*/
if (!getenv("no-network"))
start_network();
#ifdef GPROF
/*
* Fire up the gprof support.
*/
start_gprof();
#endif
}
/*
* Check for an environment variable named by `option' whose value
* is a disk device/partition name in some vaguely canonical format.
* Return nonzero iff *out_bio is the successfully opened disk partition.
* This tries to grok either BSD and Linux device and (optional)
* partition syntax, or any combination of flavors, and strips
* a leading "/dev/" which people like to prepend to the device name.
*/
static int
disk_option(const char *option, const char *ro_option,
oskit_blkio_t **out_bio)
{
int rc;
char *s, *disk, *part;
s = getenv(option);
if (!s)
return 0;
if (!strncmp(s, "/dev/", 5))
s += 5;
disk = strdup(s);
if (disk[0] == 'w' && disk[1] == 'd') /* BSD wd => Linux hd */
disk[0] = 'h';
if (disk[1] == 'd' && (disk[0] == 's' || disk[0] == 'h')) {
if (isdigit(disk[2])) /* linux uses hda, not hd0 */
disk[2] = disk[2] - '0' + 'a';
if (disk[3] == '\0')
part = 0; /* use whole disk */
else if (isdigit(disk[3])) {
/* insert "s" for slice syntax */
part = strdup(&disk[2]);
part[0] = 's';
disk[3] = '\0'; /* terminate disk */
}
else {
part = strdup(&disk[3]);
disk[3] = '\0';
}
}
else {
/*
* Can't guess syntax, presume it was for whole disk.
*/
disk = s;
part = 0;
}
osenv_process_lock();
rc = start_disk(disk, part, ro_option && getenv(ro_option),
out_bio);
osenv_process_unlock();
free(disk);
if (part)
free(part);
if (rc) {
printf("start_disk() failed: errno 0x%x\n", rc);
exit(rc);
}
return 1;
}
|