diff options
Diffstat (limited to 'kernel/old/kernel.c')
-rw-r--r-- | kernel/old/kernel.c | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/kernel/old/kernel.c b/kernel/old/kernel.c new file mode 100644 index 0000000..ce2e9dd --- /dev/null +++ b/kernel/old/kernel.c @@ -0,0 +1,400 @@ +/** +** @file kernel.c +** +** @author CSCI-452 class of 20245 +** +** @brief Kernel support routines +*/ + +#define KERNEL_SRC + +#include <common.h> +#include <cio.h> +#include <clock.h> +#include <kmem.h> +#include <procs.h> +#include <sio.h> +#include <syscalls.h> +#include <user.h> +#include <userids.h> +#include <vm.h> + +/* +** PRIVATE DEFINITIONS +*/ + +/* +** PRIVATE DATA TYPES +*/ + +/* +** PRIVATE GLOBAL VARIABLES +*/ + +/* +** PUBLIC GLOBAL VARIABLES +*/ + +// character buffers, usable throughout the OS +// nto guaranteed to retain their contents across an exception return +char b256[256]; // primarily used for message creation +char b512[512]; // used by PANIC macro + +/* +** PRIVATE FUNCTIONS +*/ + +/* +** PRIVATE FUNCTIONS +*/ + +/** +** report - report the system configuration +** +** Prints configuration information about the OS on the console monitor. +** +** @param dtrace Decode the TRACE options +*/ +static void kreport(bool_t dtrace) +{ + cio_puts("\n-------------------------------\n"); + cio_printf("Config: N_PROCS = %d", N_PROCS); + cio_printf(" N_PRIOS = %d", N_PRIOS); + cio_printf(" N_STATES = %d", N_STATES); + cio_printf(" CLOCK = %dHz\n", CLOCK_FREQ); + + // This code is ugly, but it's the simplest way to + // print out the values of compile-time options + // without spending a lot of execution time at it. + + cio_puts("Options: " +#ifdef RPT_INT_UNEXP + " R-uint" +#endif +#ifdef RPT_INT_MYSTERY + " R-mint" +#endif +#ifdef TRACE_CX + " CX" +#endif +#ifdef CONSOLE_STATS + " Cstats" +#endif + ); // end of cio_puts() call + +#ifdef SANITY + cio_printf(" SANITY = %d", SANITY); +#endif +#ifdef STATUS + cio_printf(" STATUS = %d", STATUS); +#endif + +#if TRACE > 0 + cio_printf(" TRACE = 0x%04x\n", TRACE); + + // decode the trace settings if that was requested + if (TRACING_SOMETHING && dtrace) { + // this one is simpler - we rely on string literal + // concatenation in the C compiler to create one + // long string to print out + + cio_puts("Tracing:" +#if TRACING_PCB + " PCB" +#endif +#if TRACING_VM + " VM" +#endif +#if TRACING_QUEUE + " QUE" +#endif +#if TRACING_SCHED + " SCHED" +#endif +#if TRACING_DISPATCH + " DISPATCH" +#endif +#if TRACING_SYSCALLS + " SCALL" +#endif +#if TRACING_SYSRETS + " SRET" +#endif +#if TRACING_EXIT + " EXIT" +#endif +#if TRACING_INIT + " INIT" +#endif +#if TRACING_KMEM + " KM" +#endif +#if TRACING_KMEM_FREELIST + " KMFL" +#endif +#if TRACING_KMEM_INIT + " KMIN" +#endif +#if TRACING_FORK + " FORK" +#endif +#if TRACING_EXEC + " EXEC" +#endif +#if TRACING_SIO_STAT + " S_STAT" +#endif +#if TRACING_SIO_ISR + " S_ISR" +#endif +#if TRACING_SIO_RD + " S_RD" +#endif +#if TRACING_SIO_WR + " S_WR" +#endif +#if TRACING_USER + " USER" +#endif +#if TRACING_ELF + " ELF" +#endif + ); // end of cio_puts() call + } +#endif /* TRACE > 0 */ + + cio_putchar('\n'); +} + +#if defined(CONSOLE_STATS) +/** +** stats - callback routine for console statistics +** +** Called by the CIO module when a key is pressed on the +** console keyboard. Depending on the key, it will print +** statistics on the console display, or will cause the +** user shell process to be dispatched. +** +** This code runs as part of the CIO ISR. +*/ +static void stats(int code) +{ + switch (code) { + case 'a': // dump the active table + ptable_dump("\nActive processes", false); + break; + + case 'c': // dump context info for all active PCBs + ctx_dump_all("\nContext dump"); + break; + + case 'p': // dump the active table and all PCBs + ptable_dump("\nActive processes", true); + break; + + case 'q': // dump the queues + // code to dump out any/all queues + pcb_queue_dump("R", ready, true); + pcb_queue_dump("W", waiting, true); + pcb_queue_dump("S", sleeping, true); + pcb_queue_dump("Z", zombie, true); + pcb_queue_dump("I", sioread, true); + break; + + case 'r': // print system configuration information + report(true); + break; + + // ignore CR and LF + case '\r': // FALL THROUGH + case '\n': + break; + + default: + cio_printf("console: unknown request '0x%02x'\n", code); + // FALL THROUGH + + case 'h': // help message + cio_puts("\nCommands:\n" + " a -- dump the active table\n" + " c -- dump contexts for active processes\n" + " h -- this message\n" + " p -- dump the active table and all PCBs\n" + " q -- dump the queues\n" + " r -- print system configuration\n"); + break; + } +} +#endif + +/* +** PUBLIC FUNCTIONS +*/ + +/** +** main - system initialization routine +** +** Called by the startup code immediately before returning into the +** first user process. +** +** Making this type 'int' keeps the compiler happy. +*/ +int main(void) +{ + /* + ** BOILERPLATE CODE - taken from basic framework + ** + ** Initialize interrupt stuff. + */ + + init_interrupts(); // IDT and PIC initialization + + /* + ** Console I/O system. + ** + ** Does not depend on the other kernel modules, so we can + ** initialize it before we initialize the kernel memory + ** and queue modules. + */ + +#if defined(CONSOLE_STATS) + cio_init(stats); +#else + cio_init(NULL); // no console callback routine +#endif + + cio_clearscreen(); // wipe out whatever is there + + /* + ** TERM-SPECIFIC CODE STARTS HERE + */ + + /* + ** Initialize various OS modules + ** + ** Other modules (clock, SIO, syscall, etc.) are expected to + ** install their own ISRs in their initialization routines. + */ + + cio_puts("System initialization starting.\n"); + cio_puts("-------------------------------\n"); + + cio_puts("Modules:"); + + // call the module initialization functions, being + // careful to follow any module precedence requirements + + km_init(); // MUST BE FIRST +#if TRACING_KMEM || TRACING_KMEM_FREE + delay(DELAY_2_SEC); // approximately +#endif + + // other module initialization calls here + clk_init(); // clock + pcb_init(); // process (PCBs, queues, scheduler) +#if TRACING_PCB + delay(DELAY_2_SEC); +#endif + sio_init(); // serial i/o + sys_init(); // system call +#if TRACING_SYSCALLS || TRACING_SYSRETS + delay(DELAY_2_SEC); +#endif + vm_init(); // virtual memory + user_init(); // user code handling + + cio_puts("\nModule initialization complete.\n"); + + // report our configuration options + kreport(true); + cio_puts("-------------------------------\n"); + + delay(DELAY_2_SEC); + + /* + ** Other tasks typically performed here: + ** + ** Enabling any I/O devices (e.g., SIO xmit/rcv) + */ + + /* + ** Create the initial user process + ** + ** This code is largely stolen from the fork() and exec() + ** implementations in syscalls.c; if those change, this must + ** also change. + */ + + // if we can't get a PCB, there's no use continuing! + assert(pcb_alloc(&init_pcb) == SUCCESS); + + // fill in the necessary details + init_pcb->pid = PID_INIT; + init_pcb->state = STATE_NEW; + init_pcb->priority = PRIO_HIGH; + + // find the 'init' program + prog_t *prog = user_locate(Init); + assert(prog != NULL); + + // command-line arguments for 'init' + const char *args[2] = { "init", NULL }; + + // load it + assert(user_load(prog, init_pcb, args, true) == SUCCESS); + + // send it on its merry way + schedule(init_pcb); + dispatch(); + +#ifdef TRACE_CX + // if we're using a scrolling region, wait a bit more and then set it up + delay(DELAY_7_SEC); + + // define a scrolling region in the top 7 lines of the screen + cio_setscroll(0, 7, 99, 99); + + // clear it + cio_clearscroll(); + + // clear the top line + cio_puts_at( + 0, 0, + "* "); + // separator + cio_puts_at( + 0, 6, + "================================================================================"); +#endif + + /* + ** END OF TERM-SPECIFIC CODE + ** + ** Finally, report that we're all done. + */ + + cio_puts("System initialization complete.\n"); + cio_puts("-------------------------------\n"); + + sio_enable(SIO_RX); + +#if 0 + // produce a "system state" report + cio_puts( "System status: Queues " ); + pcb_queue_dump( "R", ready, true ); + pcb_queue_dump( "W", waiting, true ); + pcb_queue_dump( "S", sleeping, true ); + pcb_queue_dump( "Z", zombie, true ); + pcb_queue_dump( "I", sioread, true ); + ptable_dump_counts(); + pcb_dump( "Current: ", current, true ); + + delay( DELAY_3_SEC ); + + vm_print( current->pdir, true, TwoLevel ); + + delay( DELAY_3_SEC ); +#endif + + return 0; +} |