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 }