os161-1.99
 All Data Structures
main.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
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  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 /*
00031  * Main.
00032  */
00033 
00034 #include <types.h>
00035 #include <kern/errno.h>
00036 #include <kern/reboot.h>
00037 #include <kern/unistd.h>
00038 #include <lib.h>
00039 #include <spl.h>
00040 #include <clock.h>
00041 #include <thread.h>
00042 #include <proc.h>
00043 #include <current.h>
00044 #include <synch.h>
00045 #include <vm.h>
00046 #include <mainbus.h>
00047 #include <vfs.h>
00048 #include <device.h>
00049 #include <syscall.h>
00050 #include <test.h>
00051 #include <version.h>
00052 #include "autoconf.h"  // for pseudoconfig
00053 
00054 
00055 /*
00056  * These two pieces of data are maintained by the makefiles and build system.
00057  * buildconfig is the name of the config file the kernel was configured with.
00058  * buildversion starts at 1 and is incremented every time you link a kernel. 
00059  *
00060  * The purpose is not to show off how many kernels you've linked, but
00061  * to make it easy to make sure that the kernel you just booted is the
00062  * same one you just built.
00063  */
00064 extern const int buildversion;
00065 extern const char buildconfig[];
00066 
00067 /*
00068  * Copyright message for the OS/161 base code.
00069  */
00070 static const char harvard_copyright[] =
00071     "Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009\n"
00072     "   President and Fellows of Harvard College.  All rights reserved.\n";
00073 
00074 
00075 /*
00076  * Initial boot sequence.
00077  */
00078 static
00079 void
00080 boot(void)
00081 {
00082         /*
00083          * The order of these is important!
00084          * Don't go changing it without thinking about the consequences.
00085          *
00086          * Among other things, be aware that console output gets
00087          * buffered up at first and does not actually appear until
00088          * mainbus_bootstrap() attaches the console device. This can
00089          * be remarkably confusing if a bug occurs at this point. So
00090          * don't put new code before mainbus_bootstrap if you don't
00091          * absolutely have to.
00092          *
00093          * Also note that the buffer for this is only 1k. If you
00094          * overflow it, the system will crash without printing
00095          * anything at all. You can make it larger though (it's in
00096          * dev/generic/console.c).
00097          */
00098 
00099         kprintf("\n");
00100         kprintf("OS/161 base system version %s\n", BASE_VERSION);
00101         kprintf("%s", harvard_copyright);
00102         kprintf("\n");
00103 
00104         kprintf("Put-your-group-name-here's system version %s (%s #%d)\n", 
00105                 GROUP_VERSION, buildconfig, buildversion);
00106         kprintf("\n");
00107 
00108         /* Early initialization. */
00109         ram_bootstrap();
00110         proc_bootstrap();
00111         thread_bootstrap();
00112         hardclock_bootstrap();
00113         vfs_bootstrap();
00114 
00115         /* Probe and initialize devices. Interrupts should come on. */
00116         kprintf("Device probe...\n");
00117         KASSERT(curthread->t_curspl > 0);
00118         mainbus_bootstrap();
00119         KASSERT(curthread->t_curspl == 0);
00120         /* Now do pseudo-devices. */
00121         pseudoconfig();
00122         kprintf("\n");
00123 
00124         /* Late phase of initialization. */
00125         vm_bootstrap();
00126         kprintf_bootstrap();
00127         thread_start_cpus();
00128 
00129         /* Default bootfs - but ignore failure, in case emu0 doesn't exist */
00130         vfs_setbootfs("emu0");
00131 
00132 
00133         /*
00134          * Make sure various things aren't screwed up.
00135          */
00136         COMPILE_ASSERT(sizeof(userptr_t) == sizeof(char *));
00137         COMPILE_ASSERT(sizeof(*(userptr_t)0) == sizeof(char));
00138 }
00139 
00140 /*
00141  * Shutdown sequence. Opposite to boot().
00142  */
00143 static
00144 void
00145 shutdown(void)
00146 {
00147 
00148         kprintf("Shutting down.\n");
00149         
00150         vfs_clearbootfs();
00151         vfs_clearcurdir();
00152         vfs_unmountall();
00153 
00154         thread_shutdown();
00155 
00156         splhigh();
00157 }
00158 
00159 /*****************************************/
00160 
00161 /*
00162  * reboot() system call.
00163  *
00164  * Note: this is here because it's directly related to the code above,
00165  * not because this is where system call code should go. Other syscall
00166  * code should probably live in the "syscall" directory.
00167  */
00168 int
00169 sys_reboot(int code)
00170 {
00171         switch (code) {
00172             case RB_REBOOT:
00173             case RB_HALT:
00174             case RB_POWEROFF:
00175                 break;
00176             default:
00177                 return EINVAL;
00178         }
00179 
00180         shutdown();
00181 
00182         switch (code) {
00183             case RB_HALT:
00184                 kprintf("The system is halted.\n");
00185                 mainbus_halt();
00186                 break;
00187             case RB_REBOOT:
00188                 kprintf("Rebooting...\n");
00189                 mainbus_reboot();
00190                 break;
00191             case RB_POWEROFF:
00192                 kprintf("The system is halted.\n");
00193                 mainbus_poweroff();
00194                 break;
00195         }
00196 
00197         panic("reboot operation failed\n");
00198         return 0;
00199 }
00200 
00201 /*
00202  * Kernel main. Boot up, then fork the menu thread; wait for a reboot
00203  * request, and then shut down.
00204  */
00205 void
00206 kmain(char *arguments)
00207 {
00208         boot();
00209 
00210         menu(arguments);
00211 
00212         /* Should not get here */
00213 }
 All Data Structures