summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-03 12:31:21 -0400
commita524eb3846aac4d1b38f08cba49ff3503107042f (patch)
treedbe81fccf975f646a681e4fdcebd227cdfb98774 /kernel
parentnew libs (diff)
downloadcomus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.gz
comus-a524eb3846aac4d1b38f08cba49ff3503107042f.tar.bz2
comus-a524eb3846aac4d1b38f08cba49ff3503107042f.zip
move old kernel code (for now) into kernel/old, trying to get long mode
Diffstat (limited to 'kernel')
-rw-r--r--kernel/entry.S158
-rw-r--r--kernel/include/comus/memory.h1
-rw-r--r--kernel/include/comus/memory/mapping.h20
-rw-r--r--kernel/kernel.c399
-rw-r--r--kernel/kernel.ld47
-rw-r--r--kernel/old/cio.c (renamed from kernel/cio.c)0
-rw-r--r--kernel/old/drivers/clock.c (renamed from kernel/clock.c)8
-rw-r--r--kernel/old/drivers/serial.c (renamed from kernel/sio.c)61
-rw-r--r--kernel/old/include/bindings.h73
-rw-r--r--kernel/old/include/bootstrap.h119
-rw-r--r--kernel/old/include/cio.h287
-rw-r--r--kernel/old/include/clock.h55
-rw-r--r--kernel/old/include/compat.h132
-rw-r--r--kernel/old/include/debug.h356
-rw-r--r--kernel/old/include/defs.h130
-rw-r--r--kernel/old/include/kdefs.h157
-rw-r--r--kernel/old/include/klib.h57
-rw-r--r--kernel/old/include/kmem.h138
-rw-r--r--kernel/old/include/list.h68
-rw-r--r--kernel/old/include/params.h33
-rw-r--r--kernel/old/include/procs.h457
-rw-r--r--kernel/old/include/serial.h3
-rw-r--r--kernel/old/include/sio.h168
-rw-r--r--kernel/old/include/support.h86
-rw-r--r--kernel/old/include/syscalls.h80
-rw-r--r--kernel/old/include/types.h13
-rw-r--r--kernel/old/include/user.h139
-rw-r--r--kernel/old/include/vm.h501
-rw-r--r--kernel/old/include/vmtables.h43
-rw-r--r--kernel/old/include/x86/arch.h299
-rw-r--r--kernel/old/include/x86/ops.h395
-rw-r--r--kernel/old/include/x86/pic.h136
-rw-r--r--kernel/old/include/x86/pit.h81
-rw-r--r--kernel/old/include/x86/uart.h348
-rw-r--r--kernel/old/isrs.S (renamed from kernel/isrs.S)0
-rw-r--r--kernel/old/kernel.c400
-rw-r--r--kernel/old/kmem.c (renamed from kernel/kmem.c)0
-rw-r--r--kernel/old/list.c (renamed from kernel/list.c)0
-rw-r--r--kernel/old/procs.c (renamed from kernel/procs.c)0
-rw-r--r--kernel/old/support.c (renamed from kernel/support.c)0
-rw-r--r--kernel/old/syscalls.c (renamed from kernel/syscalls.c)0
-rw-r--r--kernel/old/user.c (renamed from kernel/user.c)0
-rw-r--r--kernel/old/vm.c (renamed from kernel/vm.c)0
-rw-r--r--kernel/old/vmtables.c (renamed from kernel/vmtables.c)0
-rw-r--r--kernel/startup.S161
45 files changed, 4938 insertions, 671 deletions
diff --git a/kernel/entry.S b/kernel/entry.S
new file mode 100644
index 0000000..5d763ed
--- /dev/null
+++ b/kernel/entry.S
@@ -0,0 +1,158 @@
+ .globl _start
+ .globl kernel_pml4
+ .globl kernel_pdpt_0
+ .globl kernel_pd_0
+ .globl kernel_pt_0
+ .globl paging_pt
+ .globl bootstrap_pt
+ .extern main
+ .extern GDT
+
+ .section .bss
+
+ # kernel page tables
+ .align 4096
+kernel_pml4: # reserve memory for initial 512 pml4 entires
+ .skip 4096
+kernel_pdpt_0: # reserve memory for initial 512 pdpt entires
+ .skip 4096
+kernel_pd_0: # reserve memory for initial 512 pd entries
+ .skip 4096
+kernel_pt_0: # reserve memory for initial 512 pt entries
+ .skip 4096
+paging_pt: # reserve pages for pager mappings
+ .skip 4096
+bootstrap_pt: # reserve pages to bootstrap pager
+ .skip 4096
+
+ # kernel stack
+ .align 16
+kern_stack_start:
+ .skip 8192
+kern_stack_end:
+
+ .section .rodata
+ .align 16
+
+ # access bits
+ .set PRESENT, 1 << 7
+ .set NOT_SYS, 1 << 4
+ .set EXEC, 1 << 3
+ .set DC, 1 << 2
+ .set RW, 1 << 1
+ .set ACCESSED, 1 << 0
+
+ # flag bits
+ .set GRAN_4K, 1 << 7
+ .set SZ_32, 1 << 6
+ .set LONG_MODE, 1 << 5
+
+ # kernel gdt (long mode)
+GDT:
+ GDT.Null:
+ .quad 0
+
+ GDT.Code:
+ .byte 0
+ .byte PRESENT | NOT_SYS | EXEC | RW
+ .byte GRAN_4K | LONG_MODE | 0xF
+ .byte 0
+
+ GDT.Data:
+ .long 0xFFFF
+ .byte 0
+ .byte PRESENT | NOT_SYS | RW
+ .byte GRAN_4K | SZ_32 | 0xF
+ .byte 0
+
+ GDT.TSS:
+ .long 0x00000068
+ .long 0x00CF8900
+
+ GDT.Pointer:
+ .short . - GDT - 1
+ .quad GDT - .
+
+ .section .text
+ .code32
+
+_start:
+ # enable interrupts
+ cli
+
+ # setup stack
+ movl $kern_stack_end, %esp
+ movl $kern_stack_end, %ebp
+
+ # save multiboot (if using multiboot)
+ pushl $0
+ push %ebx
+ pushl $0
+ push %eax
+
+ # zero out kernel page table
+ movl $0x1000, %edi # kernel is loaded at 0x1000
+ movl %edi, %cr3
+ xorl %eax, %eax
+ movl $4096, %ecx # zero 4096 pages
+ rep stosl
+ movl %cr3, %edi
+
+ # identity map kernel
+ movl $kernel_pdpt_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x2003.
+ movl $kernel_pdpt_0, %edi # Add 0x1000 to the desination index.
+ movl $kernel_pd_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x3003.
+ movl $kernel_pd_0, %edi # Add 0x1000 to the desination index.
+ movl $kernel_pt_0 + 3, (%edi) # Set the uint32_t at the desination index to 0x4003.
+ movl $kernel_pt_0, %edi # Add 0x1000 to the desination index.
+
+ movl $0x00000003, %ebx # Entry value to set
+ movl $512, %ecx # Loop count
+
+set_entry:
+ # set entires in mapping
+ movl %ebx, (%edi) # Set the uint32_t at the desination index to the B-register
+ addl $0x1000, %ebx # Add 0x1000 to the B-register
+ addl $8, %edi # Add eight to the desination index
+ loop set_entry
+
+ # enable page address extension
+ movl %cr4, %eax
+ orl $(1 << 5), %eax
+ movl %eax, %cr4
+
+ # enable long mode
+ movl $0xC0000080, %eax
+ rdmsr
+ orl $(1 << 8), %eax
+ wrmsr
+
+ # enable paging
+ movl %cr0, %eax
+ orl $(1 << 31), %eax
+ movl %eax, %cr0
+
+ # load gdt
+ lgdt GDT.Pointer
+ ljmp $16, $code64
+
+ .code64
+code64:
+
+ movw $16, %dx # set segment registers
+ movw %dx, %ds
+ movw %dx, %ss
+
+ xorq %rbp, %rbp # set ebp to 0 so we know where to end stack traces
+
+ pop %rdi # pop possible multiboot header
+ pop %rsi
+
+ sti
+ call main
+ cli
+
+ halt:
+ hlt
+ jmp halt
+
diff --git a/kernel/include/comus/memory.h b/kernel/include/comus/memory.h
new file mode 100644
index 0000000..938bc6b
--- /dev/null
+++ b/kernel/include/comus/memory.h
@@ -0,0 +1 @@
+#include <memory/mapping.h>
diff --git a/kernel/include/comus/memory/mapping.h b/kernel/include/comus/memory/mapping.h
new file mode 100644
index 0000000..e1b7102
--- /dev/null
+++ b/kernel/include/comus/memory/mapping.h
@@ -0,0 +1,20 @@
+/**
+ * @file memory.h
+ *
+ * @author Freya Murphy
+ *
+ * Kernel memory declarations
+ */
+
+#ifndef _MEMORY_MAPPING_H
+#define _MEMORY_MAPPING_H
+
+// paging
+#define PAGE_SIZE 4096
+#define PAGE_PRESENT 0x1
+#define PAGE_WRITE 0x2
+#define PAGE_USER 0x4
+#define PAGE_HUGE 0x80
+#define PAGE_GLOBAL 0x100
+
+#endif
diff --git a/kernel/kernel.c b/kernel/kernel.c
index ce2e9dd..075c878 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -1,400 +1,5 @@
-/**
-** @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;
+void main(void) {
+ while (1) ;
}
diff --git a/kernel/kernel.ld b/kernel/kernel.ld
index 83f211c..eed5e20 100644
--- a/kernel/kernel.ld
+++ b/kernel/kernel.ld
@@ -1,71 +1,30 @@
-/*
-** Simple linker script for the 20245 kernel.
-*/
-
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
- /* Link the kernel at this address. */
- /* Must match what is defined in vm.h! */
- . = 0x80010000;
+ . = 1M;
- .text : AT(0x10000) {
+ .text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
- /* standard symbols */
- PROVIDE(etext = .);
- PROVIDE(_etext = .);
-
- /* put read-only data next */
.rodata : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
- /* Could put STABs here */
- /*
- .stab : {
- PROVIDE(__STAB_BEGIN__ = .);
- *(.stab);
- PROVIDE(__STAB_END__ = .);
- }
- .stabstr : {
- PROVIDE(__STABSTR_BEGIN__ = .);
- *(.stabstr);
- PROVIDE(__STABSTR_END__ = .);
- }
- */
-
- /* Align the data segment at the next page boundary */
. = ALIGN(0x1000);
- PROVIDE(data = .);
- PROVIDE(_data = .);
-
- /* The data segment */
.data : {
*(.data .data.*)
}
- PROVIDE(edata = .);
- PROVIDE(_edata = .);
-
- /* page-align the BSS */
. = ALIGN(0x1000);
- PROVIDE(__bss_start = .);
-
.bss : {
- *(.bss .bss.*)
*(COMMON)
+ *(.bss .bss.*)
}
- PROVIDE(end = .);
- PROVIDE(_end = .);
-
/DISCARD/ : {
*(.stab .stab_info .stabstr)
*(.eh_frame .eh_frame_hdr)
diff --git a/kernel/cio.c b/kernel/old/cio.c
index deb6b76..deb6b76 100644
--- a/kernel/cio.c
+++ b/kernel/old/cio.c
diff --git a/kernel/clock.c b/kernel/old/drivers/clock.c
index 7af47b7..9f3d4be 100644
--- a/kernel/clock.c
+++ b/kernel/old/drivers/clock.c
@@ -1,11 +1,3 @@
-/**
-** @file clock.c
-**
-** @author CSCI-452 class of 20245
-**
-** @brief Clock module implementation
-*/
-
#define KERNEL_SRC
#include <common.h>
diff --git a/kernel/sio.c b/kernel/old/drivers/serial.c
index 8bcc8a1..d6572e5 100644
--- a/kernel/sio.c
+++ b/kernel/old/drivers/serial.c
@@ -1,64 +1,3 @@
-/**
-** @file sio.c
-**
-** @author Warren R. Carithers
-**
-** @brief SIO module
-**
-** For maximum compatibility from semester to semester, this code uses
-** several "stand-in" type names and macros which should be defined
-** in the accompanying "compat.h" header file if they're not part of
-** the baseline system:
-**
-** standard-sized integer types: intN_t, uintN_t
-** other types: PCBTYPE, QTYPE
-** scheduler functions: SCHED, DISPATCH
-** queue functions: QCREATE, QLENGTH, QDEQUE
-** other functions: SLENGTH
-** sio read queue: QNAME
-**
-** Our SIO scheme is very simple:
-**
-** Input: We maintain a buffer of incoming characters that haven't
-** yet been read by processes. When a character comes in, if
-** there is no process waiting for it, it goes in the buffer;
-** otherwise, the first waiting process is awakeneda and it
-** gets the character.
-**
-** When a process invokes readch(), if there is a character in
-** the input buffer, the process gets it; otherwise, it is
-** blocked until input appears
-**
-** Communication with system calls is via two routines.
-** sio_readc() returns the first available character (if
-** there is one), resetting the input variables if this was
-** the last character in the buffer. If there are no
-** characters in the buffer, sio_read() returns a -1
-** (presumably so the requesting process can be blocked).
-**
-** sio_read() copies the contents of the input buffer into
-** a user-supplied buffer. It returns the number of characters
-** copied. If there are no characters available, return a -1.
-**
-** Output: We maintain a buffer of outgoing characters that haven't
-** yet been sent to the device, and an indication of whether
-** or not we are in the middle of a transmit sequence. When
-** an interrupt comes in, if there is another character to
-** send we copy it to the transmitter buffer; otherwise, we
-** end the transmit sequence.
-**
-** Communication with user processes is via three functions.
-** sio_writec() writes a single character; sio_write()
-** writes a sized buffer full of characters; sio_puts()
-** prints a NUL-terminated string. If we are in the middle
-** of a transmit sequence, all characters will be added
-** to the output buffer (from where they will be sent
-** automatically); otherwise, we send the first character
-** directly, add the rest of the characters (if there are
-** any) to the output buffer, and set the "sending" flag
-** to indicate that we're expecting a transmitter interrupt.
-*/
-
#define KERNEL_SRC
// this should do all includes required for this OS
diff --git a/kernel/old/include/bindings.h b/kernel/old/include/bindings.h
new file mode 100644
index 0000000..365abc9
--- /dev/null
+++ b/kernel/old/include/bindings.h
@@ -0,0 +1,73 @@
+/**
+ * @file bindings.h
+ * @author Freya Murphy <freya@freyacat.org>
+ *
+ * C-style function definitions binded to their named assembly instruction.
+ */
+
+#ifndef _BINDINGS_H
+#define _BINDINGS_H
+#include <types.h>
+
+static inline uint8_t inb(uint16_t port)
+{
+ uint8_t ret;
+ __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline void outb(uint16_t port, uint8_t val)
+{
+ __asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
+}
+
+static inline uint16_t inw(uint16_t port)
+{
+ uint16_t ret;
+ __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline void outw(uint16_t port, uint16_t val)
+{
+ __asm__ volatile("outw %0, %1" : : "a"(val), "Nd"(port));
+}
+
+static inline uint32_t inl(uint16_t port)
+{
+ uint32_t ret;
+ __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline void outl(uint16_t port, uint32_t val)
+{
+ __asm__ volatile("outl %0, %1" : : "a"(val), "Nd"(port));
+}
+
+static inline void io_wait(void)
+{
+ outb(0x80, 0);
+}
+
+static inline void sti(void)
+{
+ __asm__ volatile("sti");
+}
+
+static inline void cli(void)
+{
+ __asm__ volatile("cli");
+}
+
+static inline void int_wait(void)
+{
+ __asm__ volatile("sti; hlt");
+}
+
+static inline void halt(void)
+{
+ __asm__ volatile("cli; hlt");
+}
+
+#endif /* bindings.h */
diff --git a/kernel/old/include/bootstrap.h b/kernel/old/include/bootstrap.h
new file mode 100644
index 0000000..6c6dfcc
--- /dev/null
+++ b/kernel/old/include/bootstrap.h
@@ -0,0 +1,119 @@
+/*
+** SCCS ID: @(#)bootstrap.h 2.4 1/22/25
+**
+** @file bootstrap.h
+**
+** @author K. Reek
+** @author Warren R. Carithers, Garrett C. Smith
+**
+** Addresses where various stuff goes in memory.
+*/
+
+#ifndef BOOTSTRAP_H_
+#define BOOTSTRAP_H_
+
+/*
+** The boot device
+*/
+#define BDEV_FLOPPY 0x00
+#define BDEV_USB 0x80 /* hard drive */
+
+#define BDEV BDEV_USB /* default */
+
+/*
+** Bootstrap definitions
+*/
+#define BOOT_SEG 0x07c0 /* 07c0:0000 */
+#define BOOT_DISP 0x0000
+#define BOOT_ADDR ((BOOT_SEG << 4) + BOOT_DISP)
+
+#define PART2_DISP 0x0200 /* 07c0:0200 */
+#define PART2_ADDR ((BOOT_SEG << 4) + PART2_DISP)
+
+#define SECTOR_SIZE 0x200 /* 512 bytes */
+
+/* Note: this assumes the bootstrap is two sectors long! */
+#define BOOT_SIZE (SECTOR_SIZE + SECTOR_SIZE)
+
+#define OFFSET_LIMIT (0x10000 - SECTOR_SIZE)
+
+#define BOOT_SP_DISP 0x4000 /* stack pointer 07c0:4000, or 0xbc00 */
+#define BOOT_SP_ADDR ((BOOT_SEG << 4) + BOOT_SP_DISP)
+
+#define SECTOR1_END (BOOT_ADDR + SECTOR_SIZE)
+#define SECTOR2_END (BOOT_ADDR + BOOT_SIZE)
+
+// location of the user blob data
+// (three halfwords of data)
+#define USER_BLOB_DATA (SECTOR2_END - 12)
+
+/*
+** The target program itself
+*/
+#define TARGET_SEG 0x00001000 /* 1000:0000 */
+#define TARGET_ADDR 0x00010000 /* and upward */
+#define TARGET_STACK 0x00010000 /* and downward */
+
+/*
+** The Global Descriptor Table (0000:0500 - 0000:2500)
+*/
+#define GDT_SEG 0x00000050
+#define GDT_ADDR 0x00000500
+
+/* segment register values */
+#define GDT_LINEAR 0x0008 /* All of memory, R/W */
+#define GDT_CODE 0x0010 /* All of memory, R/E */
+#define GDT_DATA 0x0018 /* All of memory, R/W */
+#define GDT_STACK 0x0020 /* All of memory, R/W */
+
+/*
+** The Interrupt Descriptor Table (0000:2500 - 0000:2D00)
+*/
+#define IDT_SEG 0x00000250
+#define IDT_ADDR 0x00002500
+
+/*
+** Additional I/O ports used by the bootstrap code
+*/
+
+// keyboard controller
+#define KBD_DATA 0x60
+#define KBD_CMD 0x64
+#define KBD_STAT 0x64
+
+// status register bits
+#define KBD_OBSTAT 0x01
+#define KBD_IBSTAT 0x02
+#define KBD_SYSFLAG 0x04
+#define KBD_CMDDAT 0x08
+
+// commands
+#define KBD_P1_DISABLE 0xad
+#define KBD_P1_ENABLE 0xae
+#define KBD_RD_OPORT 0xd0
+#define KBD_WT_OPORT 0xd1
+
+#ifdef ASM_SRC
+
+// segment descriptor macros for use in assembly source files
+// layout:
+// .word lower 16 bits of limit
+// .word lower 16 bits of base
+// .byte middle 8 bits of base
+// .byte type byte
+// .byte granularity byte
+// .byte upper 8 bits of base
+// we use 4K units, so we ignore the lower 12 bits of the limit
+#define SEGNULL .word 0, 0, 0, 0
+
+#define SEGMENT(base, limit, dpl, type) \
+ .word(((limit) >> 12) & 0xffff); \
+ .word((base) & 0xffff); \
+ .byte(((base) >> 16) & 0xff); \
+ .byte(SEG_PRESENT | (dpl) | SEG_NON_SYSTEM | (type)); \
+ .byte(SEG_GRAN_4KBYTE | SEG_DB_32BIT | (((limit) >> 28) & 0xf)); \
+ .byte(((base) >> 24) & 0xff)
+
+#endif /* ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/cio.h b/kernel/old/include/cio.h
new file mode 100644
index 0000000..63bf827
--- /dev/null
+++ b/kernel/old/include/cio.h
@@ -0,0 +1,287 @@
+/**
+** SCCS ID: @(#)cio.h 2.7 1/22/25
+**
+** @file cio.h
+**
+** @author Warren R. Carithers
+** @authors K. Reek, Jon Coles
+**
+** Based on: c_io.c 1.13 (Ken Reek, Jon Coles, Warren R. Carithers)
+**
+** Declarations and descriptions of console I/O routines
+**
+** These routines provide a rudimentary capability for printing to
+** the screen and reading from the keyboard.
+**
+** Screen output:
+** There are two families of functions. The first provides a window
+** that behaves in the usual manner: writes extending beyond the right
+** edge of the window wrap around to the next line, the top line
+** scrolls off the window to make room for new lines at the bottom.
+** However, you may choose what part of the screen contains this
+** scrolling window. This allows you to print some text at fixed
+** locations on the screen while the rest of the screen scrolls.
+**
+** The second family allows for printing at fixed locations on the
+** screen. No scrolling or line wrapping are done for these functions.
+** It is not intended that these functions be used to write in the
+** scrolling area of the screen.
+**
+** In both sets of functions, the (x,y) coordinates are interpreted
+** as (column,row), with the upper left corner of the screen being
+** (0,0) and the lower right corner being (79,24).
+**
+** The printf provided in both sets of functions has the same
+** conversion capabilities. Format codes are of the form:
+**
+** %-0WC
+**
+** where "-", "0", and "W" are all optional:
+** "-" is the left-adjust flag (default is right-adjust)
+** "0" is the zero-fill flag (default is space-fill)
+** "W" is a number specifying the minimum field width (default: 1 )
+** and "C" is the conversion type, which must be one of these:
+** "c" print a single character
+** "s" print a null-terminated string
+** "d" print an integer as a decimal value
+** "x" print an integer as a hexadecimal value
+** "o" print an integer as a octal value
+**
+** Keyboard input:
+** Two functions are provided: getting a single character and getting
+** a newline-terminated line. A third function returns a count of
+** the number of characters available for immediate reading.
+** No conversions are provided (yet).
+*/
+
+#ifndef CIO_H_
+#define CIO_H_
+
+#ifndef ASM_SRC
+
+// EOT indicator (control-D)
+#define EOT '\04'
+
+/*****************************************************************************
+**
+** INITIALIZATION ROUTINES
+**
+** Initializes the I/O system.
+*/
+
+/**
+** cio_init
+**
+** Initializes the I/O routines. Must be called before
+** any CIO functions can be used.
+**
+** @param notify pointer to an input notification function, or NULL
+*/
+void cio_init(void (*notify)(int));
+
+/*****************************************************************************
+**
+** SCROLLING OUTPUT ROUTINES
+**
+** Each operation begins at the current cursor position and advances
+** it. If a newline is output, the reminder of that line is cleared.
+** Output extending past the end of the line is wrapped. If the
+** cursor is moved below the scrolling region's bottom edge, scrolling
+** is delayed until the next output is produced.
+*/
+
+/**
+** cio_setscroll
+**
+** This sets the scrolling region to be the area defined by the arguments.
+** The remainder of the screen does not scroll and may be used to display
+** data you do not want to move. By default, the scrolling region is the
+** entire screen. X and Y coordinates begin at 0 in the upper left corner
+** of the screen.
+**
+** @param min_x,min_y upper-left corner of the region
+** @param max_x,max_y lower-right corner of the region
+*/
+void cio_setscroll(unsigned int min_x, unsigned int min_y, unsigned int max_x,
+ unsigned int max_y);
+
+/**
+** cio_moveto
+**
+** Moves the cursor to the specified position. (0,0) indicates
+** the upper left corner of the scrolling region. Subsequent
+** output will begin at the cursor position.
+**
+** @param x,y desired coordinate position
+*/
+void cio_moveto(unsigned int x, unsigned int y);
+
+/**
+** cio_putchar
+**
+** Prints a single character.
+**
+** @param c the character to be printed
+*/
+void cio_putchar(unsigned int c);
+
+/**
+** cio_puts
+**
+** Prints the characters in the string up to but not including
+** the terminating null byte.
+**
+** @param str pointer to a NUL-terminated string to be printed
+*/
+void cio_puts(const char *str);
+
+/**
+** cio_write
+**
+** Prints "length" characters from the buffer.
+**
+** @param buf the buffer of characters
+** @param length the number of characters to print
+*/
+void cio_write(const char *buf, int length);
+
+/**
+** cio_printf
+**
+** Limited form of printf (see the beginning of this file for
+** a list of what is implemented).
+**
+** @param fmt a printf-style format control string
+** @param ... optional additional values to be printed
+*/
+void cio_printf(char *fmt, ...);
+
+/**
+** cio_scroll
+**
+** Scroll the scrolling region up by the given number of lines.
+** The output routines scroll automatically so normally you
+** do not need to call this routine yourself.
+**
+** @param lines the number of lines to scroll
+*/
+void cio_scroll(unsigned int lines);
+
+/**
+** cio_clearscroll
+**
+** Clears the entire scrolling region to blank spaces, and
+** moves the cursor to (0,0).
+*/
+void cio_clearscroll(void);
+
+/*****************************************************************************
+**
+** NON-SCROLLING OUTPUT ROUTINES
+**
+** Coordinates are relative to the entire screen: (0,0) is the upper
+** left corner. There is no line wrap or scrolling.
+*/
+
+/**
+** cio_putchar_at
+**
+** Prints the given character. If a newline is printed,
+** the rest of the line is cleared. If this happens to the
+** left of the scrolling region, the clearing stops when the
+** region is reached. If this happens inside the scrolling
+** region, the clearing stops when the edge of the region
+** is reached.
+**
+** @param x,y desired coordinate position
+** @param c the character to be printed
+*/
+void cio_putchar_at(unsigned int x, unsigned int y, unsigned int c);
+
+/**
+** cio_puts_at
+**
+** Prints the given string. cio_putchar_at is used to print
+** the individual characters; see that description for details.
+**
+** @param x,y desired coordinate position
+** @param str pointer to a NUL-terminated string to be printed
+*/
+void cio_puts_at(unsigned int x, unsigned int y, const char *str);
+
+/**
+** cio_printf_at
+**
+** Limited form of printf (see the beginning of this file for
+** a list of what is implemented).
+**
+** @param x,y desired coordinate position
+** @param fmt a printf-style format control string
+** @param ... optional additional values to be printed
+*/
+void cio_printf_at(unsigned int x, unsigned int y, char *fmt, ...);
+
+/**
+** cio_clearscreen
+**
+** This function clears the entire screen, including the scrolling region.
+*/
+void cio_clearscreen(void);
+
+/*****************************************************************************
+**
+** INPUT ROUTINES
+**
+** When interrupts are enabled, a keyboard ISR collects keystrokes
+** and saves them until the program calls for them. If the input
+** queue fills, additional characters are silently discarded.
+** When interrupts are not enabled, keystrokes made when no input
+** routines have been ** called are lost. This can cause errors in
+** the input translation because the states of the Shift and Ctrl keys
+** may not be tracked accurately. If interrupts are disabled, the user
+** is advised to refrain from typing anything except when the program is
+** waiting for input.
+*/
+
+/**
+** cio_getchar
+**
+** If the character is not immediately available, the function
+** waits until the character arrives.
+**
+** @return the next character from the keyboard input buffer
+*/
+int cio_getchar(void);
+
+/**
+** cio_gets
+**
+** This function reads a newline-terminated line from the
+** keyboard. cio_getchar is used to obtain the characters;
+** see that description for more details. The function
+** returns when:
+** a newline is entered (this is stored in the buffer)
+** ctrl-D is entered (not stored in the buffer)
+** the buffer becomes full.
+** The buffer is null-terminated in all cases.
+**
+** @param buffer destination buffer for the input character sequence
+** @param size the buffer length
+**
+** @return count of the number of characters read into the buffer
+*/
+int cio_gets(char *buffer, unsigned int size);
+
+/**
+** cio_input_queue
+**
+** This function lets the program determine whether there is input
+** available. This indicates whether or not a call to cio_getchar()
+** would block.
+**
+** @return number of characters in the input queue
+*/
+int cio_input_queue(void);
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/clock.h b/kernel/old/include/clock.h
new file mode 100644
index 0000000..674d799
--- /dev/null
+++ b/kernel/old/include/clock.h
@@ -0,0 +1,55 @@
+/**
+** @file clock.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Clock module declarations
+*/
+
+#ifndef CLOCK_H_
+#define CLOCK_H_
+
+#include <common.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// conversion functions for seconds, ms, and ticks
+// (SEC_TO_MS is defined in defs.h)
+#define MS_TO_TICKS(n) ((n))
+#define SEC_TO_TICKS(n) (MS_TO_TICKS(SEC_TO_MS(n)))
+#define TICKS_TO_SEC(n) ((n) / CLOCK_FREQ)
+#define TICKS_TO_SEC_ROUNDED(n) (((n) + (CLOCK_FREQ - 1)) / CLOCK_FREQ)
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Types
+*/
+
+/*
+** Globals
+*/
+
+// current system time
+extern uint32_t system_time;
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: clk_init
+**
+** Clock module initialization
+*/
+void clk_init(void);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/compat.h b/kernel/old/include/compat.h
new file mode 100644
index 0000000..f0c8c97
--- /dev/null
+++ b/kernel/old/include/compat.h
@@ -0,0 +1,132 @@
+/**
+** @file compat.h
+**
+** @author Warren R. Carithers
+**
+** @brief Compatibility definitions for standard modules.
+**
+** These definitions are here to simplify the integration
+** of some pre-written modules into the 452 baseline system.
+** This is used primarily for the 'kmem' and 'sio' modules.
+**
+** We use CPP symbols and not actual data types for things here,
+** as this means we don't need to include any other header files
+** into this file. This helps get around "include loops" (e.g.,
+** a.h includes b.h, which includes c.h, which includes a.h) when
+** there are many interdependencies between source files.
+*/
+
+#ifndef COMPAT_H_
+#define COMPAT_H_
+
+#include <common.h>
+#include <procs.h>
+
+/*
+** Section 1: sized integer types
+**
+** Internally, we use standard names for "sized" integer types for
+** simplicity. If those disagree with the names used in the rest of
+** the system, we take the opportunity to define our names here.
+**
+** To enable these, uncomment them, and place the apropriate
+** existing type names in place of the '?' characters.
+*/
+
+// standard "sized integer" types
+// #define int8_t ?
+// #define uint8_t ?
+// #define int16_t ?
+// #define uint16_t ?
+// #define int32_t ?
+// #define uint32_t ?
+// #define int64_t ?
+// #define uint64_t ?
+// #define bool_t ?
+
+/*
+** Section 2: other types
+**
+** Add type definitions here as needed.
+**
+** Note: we do not include the PCB and Queue declarations
+** here because we don't actually need them in this header
+** file - we're only defining CPP macros. Whatever file
+** uses these macros, however, must include the appropriate
+** headers if it uses these macros.
+**
+** To enable these, uncomment them, and place the apropriate
+** existing type names in place of the '?' characters.
+*/
+
+// type name for the PCB
+#define PCBTYPE pcb_t
+
+// type name for our queue
+#define QTYPE pcb_queue_t
+
+/*
+** Section 3: interface and behavior
+**
+** Include #define statements here as needed to define
+** the names of functions and globals used in these modules
+** in terms of the names used in the rest of the baseline.
+**
+** To enable these, uncomment them, and place the apropriate
+** existing variable or function names in place of the '?' characters.
+*/
+
+// string functions
+#define SLENGTH strlen
+
+// scheduler
+#define SCHED schedule
+
+// dispatcher
+#define DISPATCH dispatch
+
+/*
+** blocked queue for reading processes
+**
+** Define this if we are blocking processes which try to
+** read from the SIO when no characters are available.
+** Its value should be the name of the globally-visible
+** queue to be used.
+*/
+#define QNAME sioread
+
+#ifdef QNAME
+
+// Only define these macros if we need to be able to create and
+// manage a queue of things. It is expected that these will need
+// to be customized based on the names and calling sequences of
+// the appropriate functions.
+
+// invoke the queue creation function
+// examples:
+//
+// #define QCREATE(q) do {
+// _que_create( &(q), NULL );
+// } while(0)
+//
+// #define QCREATE(q) // do nothing
+
+#define QCREATE(q) // handled elsewhere for us
+
+// check to see if the queue is empty
+// examples:
+//
+// #define QEMPTY(q) queue_is_empty(q)
+// #define QEMPTY(q) (quene_length(q) > 0)
+#define QEMPTY(q) pcb_queue_empty(q)
+
+// this macro expands into code that removes a value from
+// 'q' and places it into 'd'
+#define QDEQUE(q, d) \
+ do { \
+ assert(pcb_queue_remove((q), (pcb_t **)&(d)) == SUCCESS); \
+ } while (0)
+
+#endif /* QNAME */
+
+#endif
diff --git a/kernel/old/include/debug.h b/kernel/old/include/debug.h
new file mode 100644
index 0000000..41e38cb
--- /dev/null
+++ b/kernel/old/include/debug.h
@@ -0,0 +1,356 @@
+/**
+** @file debug.h
+**
+** @author Numerous CSCI-452 classes
+**
+** Debugging macros and constants.
+**
+*/
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+// Standard system headers
+
+#include <cio.h>
+#include <support.h>
+
+// Kernel library
+
+#include <lib.h>
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** General function entry/exit announcements
+*/
+
+#ifdef ANNOUNCE_ENTRY
+// Announce that we have entered a kernel function
+// usage: ENTERING( "name" ), EXITING( "name" )
+// currently, these do not use the macro parameter, but could be
+// modified to do so; instead, we use the __func__ CPP pseudo-macro
+// to get the function name
+#define ENTERING(n) \
+ do { \
+ cio_puts(" enter " __func__); \
+ } while (0)
+#define EXITING(n) \
+ do { \
+ cio_puts(" exit " __func__); \
+ } while (0)
+#else
+#define ENTERING(m) // do nothing
+#define EXITING(m) // do nothing
+#endif
+
+/*
+** Console messages when error conditions are noted.
+*/
+
+// Warning messages to the console
+// m: message (condition, etc.)
+#define WARNING(m) \
+ do { \
+ cio_printf("\n** %s (%s @ %d): ", __func__, __FILE__, __LINE__); \
+ cio_puts(m); \
+ cio_putchar('\n'); \
+ } while (0)
+
+// Panic messages to the console
+// n: severity level
+// m: message (condition, etc.)
+#define PANIC(n, m) \
+ do { \
+ sprint(b512, "%s (%s @ %d), %d: %s\n", __func__, __FILE__, __LINE__, \
+ n, #m); \
+ kpanic(b512); \
+ } while (0)
+
+/*
+** Assertions are categorized by the "sanity level" being used in this
+** compilation; each only triggers a fault if the sanity level is at or
+** above a specific value. This allows selective enabling/disabling of
+** debugging checks.
+**
+** The sanity level is set during compilation with the CPP macro
+** "SANITY". A sanity level of 0 disables conditional assertions,
+** but not the basic assert() version.
+*/
+
+#ifndef SANITY
+// default sanity check level: check everything!
+#define SANITY 9999
+#endif
+
+// Always-active assertions
+#define assert(x) \
+ if (!(x)) { \
+ PANIC(0, x); \
+ }
+
+// only provide these macros if the sanity check level is positive
+
+#if SANITY > 0
+
+#define assert1(x) \
+ if (SANITY >= 1 && !(x)) { \
+ PANIC(1, x); \
+ }
+#define assert2(x) \
+ if (SANITY >= 2 && !(x)) { \
+ PANIC(2, x); \
+ }
+#define assert3(x) \
+ if (SANITY >= 3 && !(x)) { \
+ PANIC(3, x); \
+ }
+#define assert4(x) \
+ if (SANITY >= 4 && !(x)) { \
+ PANIC(4, x); \
+ }
+// arbitrary sanity level
+#define assertN(n, x) \
+ if (SANITY >= (n) && !(x)) { \
+ PANIC(n, x); \
+ }
+
+#else
+
+#define assert1(x) // do nothing
+#define assert2(x) // do nothing
+#define assert3(x) // do nothing
+#define assert4(x) // do nothing
+#define assertN(n, x) // do nothing
+
+#endif /* SANITY > 0 */
+
+/*
+** Tracing options are enabled by defining one or more of the T_
+** macros described in the Makefile.
+**
+** To add a tracing option:
+**
+** 1) Pick a short name for it (e.g., "PCB", "VM", ...)
+** 2) At the end of this list, add code like this, with "name"
+** replaced by your short name, and "nnnnnnnn" replaced by a
+** unique bit that will designate this tracing option:
+**
+** #ifdef T_name
+** #define TRname 0xnnnnnnnn
+** #else
+** #define TRname 0
+** #endif
+**
+** Use the next bit position following the one in last list entry.
+** 3) Add this to the end of the "TRACE" macro definition:
+**
+** | TRname
+**
+** 4) In the list of "TRACING_*" macros, add one for your option
+** (using a name that might be more descriptive) in the 'then' clause:
+**
+** #define TRACING_bettername ((TRACE & TRname) != 0)
+**
+** 5) Also add a "null" version in the 'else' clause:
+**
+** #define TRACING_bettername 0
+**
+** 6) Maybe add your T_name choice to the Makefile with an explanation
+** on the off chance you want anyone else to be able to understand
+** what it's used for. :-)
+**
+** We're making CPP work for its pay with this file.
+*/
+
+// 2^0 bit
+#ifdef T_PCB
+#define TRPCB 0x00000001
+#else
+#define TRPCB 0
+#endif
+
+#ifdef T_VM
+#define TRVM 0x00000002
+#else
+#define TRVM 0
+#endif
+
+#ifdef T_QUE
+#define TRQUEUE 0x00000004
+#else
+#define TRQUEUE 0
+#endif
+
+#ifdef T_SCH
+#define TRSCHED 0x00000008
+#else
+#define TRSCHED 0
+#endif
+
+// 2^4 bit
+#ifdef T_DSP
+#define TRDISP 0x00000010
+#else
+#define TRDISP 0
+#endif
+
+#ifdef T_SCALL
+#define TRSYSCALLS 0x00000020
+#else
+#define TRSYSCALLS 0
+#endif
+
+#ifdef T_SRET
+#define TRSYSRETS 0x00000040
+#else
+#define TRSYSRETS 0
+#endif
+
+#ifdef T_EXIT
+#define TREXIT 0x00000080
+#else
+#define TREXIT 0
+#endif
+
+// 2^8 bit
+#ifdef T_INIT
+#define TRINIT 0x00000100
+#else
+#define TRINIT 0
+#endif
+
+#ifdef T_KM
+#define TRKMEM 0x00000200
+#else
+#define TRKMEM 0
+#endif
+
+#ifdef T_KMFR
+#define TRKMEM_F 0x00000400
+#else
+#define TRKMEM_F 0
+#endif
+
+#ifdef T_KMIN
+#define TRKMEM_I 0x00000800
+#else
+#define TRKMEM_I 0
+#endif
+
+// 2^12 bit
+#ifdef T_FORK
+#define TRFORK 0x00001000
+#else
+#define TRFORK 0
+#endif
+
+#ifdef T_EXEC
+#define TREXEC 0x00002000
+#else
+#define TREXEC 0
+#endif
+
+#ifdef T_SIO
+#define TRSIO_STAT 0x00004000
+#else
+#define TRSIO_STAT 0
+#endif
+
+#ifdef T_SIOR
+#define TRSIO_RD 0x00008000
+#else
+#define TRSIO_RD 0
+#endif
+
+// 2^16 bit
+#ifdef T_SIOW
+#define TRSIO_WR 0x00010000
+#else
+#define TRSIO_WR 0
+#endif
+
+#ifdef T_USER
+#define TRUSER 0x00020000
+#else
+#define TRUSER 0
+#endif
+
+#ifdef T_ELF
+#define TRELF 0x00040000
+#else
+#define TRELF 0
+#endif
+
+// 13 bits remaining for tracing options
+// next available bit: 0x00080000
+
+#define TRACE \
+ (TRDISP | TREXIT | TRINIT | TRKMEM | TRKMEM_F | TRKMEM_I | TRPCB | \
+ TRQUEUE | TRSCHED | TREXEC | TRSIO_RD | TRSIO_STAT | TRSIO_WR | TRFORK | \
+ TRVM | TRSYSCALLS | TRSYSRETS | TRUSER | TRELF)
+
+#if TRACE > 0
+
+// compile-time expressions for testing trace options
+// usage: #if TRACING_thing
+#define TRACING_PCB ((TRACE & TRPCB) != 0)
+#define TRACING_VM ((TRACE & TRVM) != 0)
+#define TRACING_QUEUE ((TRACE & TRQUEUE) != 0)
+#define TRACING_SCHED ((TRACE & TRSCHED) != 0)
+#define TRACING_DISPATCH ((TRACE & TRDISPATCH) != 0)
+#define TRACING_SYSCALLS ((TRACE & TRSYSCALLS) != 0)
+#define TRACING_SYSRETS ((TRACE & TRSYSRETS) != 0)
+#define TRACING_EXIT ((TRACE & TREXIT) != 0)
+#define TRACING_INIT ((TRACE & TRINIT) != 0)
+#define TRACING_KMEM ((TRACE & TRKMEM) != 0)
+#define TRACING_KMEM_FREELIST ((TRACE & TRKMEM_F) != 0)
+#define TRACING_KMEM_INIT ((TRACE & TRKMEM_I) != 0)
+#define TRACING_FORK ((TRACE & TRFORK) != 0)
+#define TRACING_EXEC ((TRACE & TREXEC) != 0)
+#define TRACING_SIO_STAT ((TRACE & TRSIO_STAT) != 0)
+#define TRACING_SIO_ISR ((TRACE & TRSIO_ISR) != 0)
+#define TRACING_SIO_RD ((TRACE & TRSIO_RD) != 0)
+#define TRACING_SIO_WR ((TRACE & TRSIO_WR) != 0)
+#define TRACING_USER ((TRACE & TRUSER) != 0)
+#define TRACING_ELF ((TRACE & TRELF) != 0)
+
+// more generic tests
+#define TRACING_SOMETHING (TRACE != 0)
+
+#else
+
+// TRACE == 0, so just define these all as "false"
+
+#define TRACING_PCB 0
+#define TRACING_STACK 0
+#define TRACING_QUEUE 0
+#define TRACING_SCHED 0
+#define TRACING_DISPATCH 0
+#define TRACING_SYSCALLS 0
+#define TRACING_SYSRET 0
+#define TRACING_EXIT 0
+#define TRACING_INIT 0
+#define TRACING_KMEM 0
+#define TRACING_KMEM_FREELIST 0
+#define TRACING_KMEM_INIT 0
+#define TRACING_FORK 0
+#define TRACING_EXEC 0
+#define TRACING_SI_STAT 0
+#define TRACING_SIO_ISR 0
+#define TRACING_SIO_RD 0
+#define TRACING_SIO_WR 0
+#define TRACING_USER 0
+#define TRACING_ELF 0
+
+#define TRACING_SOMETHING 0
+
+#endif /* TRACE */
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/defs.h b/kernel/old/include/defs.h
new file mode 100644
index 0000000..018b14e
--- /dev/null
+++ b/kernel/old/include/defs.h
@@ -0,0 +1,130 @@
+/**
+** @file defs.h
+**
+** @author Warren R. Carithers
+**
+** @brief Common definitions.
+**
+** This header file defines things which are neede by all
+** parts of the system (OS and user levels).
+**
+** Things which are kernel-specific go in the kdefs.h file;
+** things which are user-specific go in the udefs.h file.
+** The correct one of these will be automatically included
+** at the end of this file.
+*/
+
+#ifndef DEFS_H_
+#define DEFS_H_
+
+/*
+** General (C and/or assembly) definitions
+**
+** This section of the header file contains definitions that can be
+** used in either C or assembly-language source code.
+*/
+
+// NULL pointer value
+//
+// we define this the traditional way so that
+// it's usable from both C and assembly
+
+#define NULL 0
+
+// predefined i/o channels
+
+#define CHAN_CIO 0
+#define CHAN_SIO 1
+
+// sizes of various things
+#define NUM_1KB 0x00000400 // 2^10
+#define NUM_4KB 0x00001000 // 2^12
+#define NUM_1MB 0x00100000 // 2^20
+#define NUM_4MB 0x00400000 // 2^22
+#define NUM_1GB 0x40000000 // 2^30
+#define NUM_2GB 0x80000000 // 2^31
+#define NUM_3GB 0xc0000000 // 1GB + 2GB
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+**
+** Anything that should not be visible to something other than
+** the C compiler should be put here.
+*/
+
+/*
+** System error codes
+**
+** These can be returned to both system functions
+** and to user system calls.
+*/
+// success!
+#define SUCCESS (0)
+#define E_SUCCESS SUCCESS
+// generic "something went wrong"
+#define E_FAILURE (-1)
+// specific failure reasons
+#define E_BAD_PARAM (-2)
+#define E_BAD_CHAN (-3)
+#define E_NO_CHILDREN (-4)
+#define E_NO_MEMORY (-5)
+#define E_NOT_FOUND (-6)
+#define E_NO_PROCS (-7)
+
+/*
+** These error codes are internal to the OS.
+*/
+#define E_EMPTY_QUEUE (-100)
+#define E_NO_PCBS (-101)
+#define E_NO_PTE (-102)
+#define E_LOAD_LIMIT (-103)
+
+// exit status values
+#define EXIT_SUCCESS (0)
+#define EXIT_FAILURE (-1)
+#define EXIT_KILLED (-101)
+#define EXIT_BAD_SYSCALL (-102)
+
+/*
+** Process priority values
+*/
+enum priority_e {
+ PRIO_HIGH,
+ PRIO_STD,
+ PRIO_LOW,
+ PRIO_DEFERRED
+ // sentinel
+ ,
+ N_PRIOS
+};
+
+// halves of various data sizes
+
+#define UI16_UPPER 0xff00
+#define UI16_LOWER 0x00ff
+
+#define UI32_UPPER 0xffff0000
+#define UI32_LOWER 0x0000ffff
+
+#define UI64_UPPER 0xffffffff00000000LL
+#define UI64_LOWER 0x00000000ffffffffLL
+
+// Simple conversion pseudo-functions usable by everyone
+
+// convert seconds to ms
+#define SEC_TO_MS(n) ((n) * 1000)
+
+#endif /* !ASM_SRC */
+
+/*
+** Level-specific definitions
+*/
+#ifdef KERNEL_SRC
+#include <kdefs.h>
+#else
+#include <udefs.h>
+#endif /* KERNEL_SRC */
+
+#endif
diff --git a/kernel/old/include/kdefs.h b/kernel/old/include/kdefs.h
new file mode 100644
index 0000000..d26fa3d
--- /dev/null
+++ b/kernel/old/include/kdefs.h
@@ -0,0 +1,157 @@
+/**
+** @file kdefs.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Kernel-only declarations.
+*/
+
+#ifndef KDEFS_H_
+#define KDEFS_H_
+
+// debugging macros
+#include <debug.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// page sizes
+#define SZ_PAGE NUM_4KB
+#define SZ_BIGPAGE NUM_4MB
+
+// kernel stack size (bytes)
+#define N_KSTKPAGES 1
+#define SZ_KSTACK (N_KSTKPAGES * SZ_PAGE)
+
+// user stack size
+#define N_USTKPAGES 2
+#define SZ_USTACK (N_USTKPAGES * SZ_PAGE)
+
+// declarations for modulus checking of (e.g.) sizes and addresses
+
+#define LOW_9_BITS 0x00000fff
+#define LOW_22_BITS 0x003fffff
+#define HIGH_20_BITS 0xfffff000
+#define HIGH_10_BITS 0xffc00000
+
+#define MOD4_BITS 0x00000003
+#define MOD4_MASK 0xfffffffc
+#define MOD4_INC 0x00000004
+#define MOD4_SHIFT 2
+
+#define MOD16_BITS 0x0000000f
+#define MOD16_MASK 0xfffffff0
+#define MOD16_INC 0x00000010
+#define MOD16_SHIFT 4
+
+#define MOD1K_BITS 0x000003ff
+#define MOD1K_MASK 0xfffffc00
+#define MOD1K_INC 0x00000400
+#define MOD1K_SHIFT 10
+
+#define MOD4K_BITS 0x00000fff
+#define MOD4K_MASK 0xfffff000
+#define MOD4K_INC 0x00001000
+#define MOD4K_SHIFT 12
+
+#define MOD1M_BITS 0x000fffff
+#define MOD1M_MASK 0xfff00000
+#define MOD1M_INC 0x00100000
+#define MOD1M_SHIFT 20
+
+#define MOD4M_BITS 0x003fffff
+#define MOD4M_MASK 0xffc00000
+#define MOD4M_INC 0x00400000
+#define MOD4M_SHIFT 22
+
+#define MOD1G_BITS 0x3fffffff
+#define MOD1G_MASK 0xc0000000
+#define MOD1G_INC 0x40000000
+#define MOD1G_SHIFT 30
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+// unit conversion macros
+#define B_TO_KB(x) (((uint_t)(x)) >> 10)
+#define B_TO_MB(x) (((uint_t)(x)) >> 20)
+#define B_TO_GB(x) (((uint_t)(x)) >> 30)
+
+#define KB_TO_B(x) (((uint_t)(x)) << 10)
+#define KB_TO_MB(x) (((uint_t)(x)) >> 10)
+#define KB_TO_GB(x) (((uint_t)(x)) >> 20)
+
+#define MB_TO_B(x) (((uint_t)(x)) << 20)
+#define MB_TO_KB(x) (((uint_t)(x)) << 10)
+#define MB_TO_GB(x) (((uint_t)(x)) >> 10)
+
+#define GB_TO_B(x) (((uint_t)(x)) << 30)
+#define GB_TO_KB(x) (((uint_t)(x)) << 20)
+#define GB_TO_MB(x) (((uint_t)(x)) << 10)
+
+// potetially useful compiler attributes
+#define ATTR_ALIGNED(x) __attribute__((__aligned__(x)))
+#define ATTR_PACKED __attribute__((__packed__))
+#define ATTR_UNUSED __attribute__((__unused__))
+
+/*
+** Utility macros
+*/
+
+//
+// macros to clear data structures
+//
+// these are usable for clearing single-valued data items (e.g.,
+// a PCB, etc.)
+#define CLEAR(v) memclr(&v, sizeof(v))
+#define CLEAR_PTR(p) memclr(p, sizeof(*p))
+
+//
+// macros for access registers and system call arguments
+//
+
+// REG(pcb,x) -- access a specific register in a process context
+#define REG(pcb, x) ((pcb)->context->x)
+
+// RET(pcb) -- access return value register in a process context
+#define RET(pcb) ((pcb)->context->eax)
+
+// ARG(pcb,n) -- access argument #n from the indicated process
+//
+// ARG(pcb,0) --> return address
+// ARG(pcb,1) --> first parameter
+// ARG(pcb,2) --> second parameter
+// etc.
+//
+// ASSUMES THE STANDARD 32-BIT ABI, WITH PARAMETERS PUSHED ONTO THE
+// STACK. IF THE PARAMETER PASSING MECHANISM CHANGES, SO MUST THIS!
+#define ARG(pcb, n) (((uint32_t *)(((pcb)->context) + 1))[(n)])
+
+/*
+** Types
+*/
+
+/*
+** Globals
+*/
+
+// general-purpose character buffer
+extern char b256[256];
+
+// buffer for use by PANIC() macro
+extern char b512[512];
+
+// kernel stack
+extern uint8_t kstack[SZ_KSTACK];
+
+/*
+** Prototypes
+*/
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/klib.h b/kernel/old/include/klib.h
new file mode 100644
index 0000000..60f59da
--- /dev/null
+++ b/kernel/old/include/klib.h
@@ -0,0 +1,57 @@
+/*
+** @file klib.h
+**
+** @author Warren R. Carithers
+**
+** Additional support functions for the kernel.
+*/
+
+#ifndef KLIB_H_
+#define KLIB_H_
+
+#include <common.h>
+
+#ifndef ASM_SRC
+
+#include <x86/ops.h>
+
+/**
+** Name: put_char_or_code( ch )
+**
+** Description: Prints a character on the console, unless it
+** is a non-printing character, in which case its hex code
+** is printed
+**
+** @param ch The character to be printed
+*/
+void put_char_or_code(int ch);
+
+/**
+** Name: backtrace
+**
+** Perform a simple stack backtrace. Could be augmented to use the
+** symbol table to print function/variable names, etc., if so desired.
+**
+** @param ebp Initial EBP to use
+** @param args Number of function argument values to print
+*/
+void backtrace(uint32_t *ebp, uint_t args);
+
+/**
+** Name: kpanic
+**
+** Kernel-level panic routine
+**
+** usage: kpanic( msg )
+**
+** Prefix routine for panic() - can be expanded to do other things
+** (e.g., printing a stack traceback)
+**
+** @param msg[in] String containing a relevant message to be printed,
+** or NULL
+*/
+void kpanic(const char *msg);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/kmem.h b/kernel/old/include/kmem.h
new file mode 100644
index 0000000..631f7ab
--- /dev/null
+++ b/kernel/old/include/kmem.h
@@ -0,0 +1,138 @@
+/**
+** @file kmem.h
+**
+** @author Warren R. Carithers
+** @author Kenneth Reek
+** @author 4003-506 class of 20013
+**
+** @brief Support for dynamic memory allocation within the OS.
+**
+** This is a basic page allocator. Each allocation request returns
+** a pointer to a single 4096-byte page of memory.
+**
+** The module also supports subddivision of pages into "slices",
+** each of which is 1KB (i.e., 1/4 of a page).
+*/
+
+#ifndef KMEM_H_
+#define KMEM_H_
+
+#define KERNEL_SRC
+
+// standard types etc.
+#include <common.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// Slab and slice sizes, in bytes
+
+#define SZ_SLAB SZ_PAGE
+#define SZ_SLICE (SZ_SLAB >> 2)
+
+// memory limits
+//
+// these determine the range of memory addresses the kmem
+// module will manage
+//
+// we won't map any memory below 1MB or above 1GB
+#define KM_LOW_CUTOFF NUM_1MB
+#define KM_HIGH_CUTOFF NUM_1GB
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Types
+*/
+
+/*
+** Globals
+*/
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: km_init
+**
+** Find what memory is present on the system and
+** construct the list of free memory blocks.
+**
+** Dependencies:
+** Must be called before any other init routine that uses
+** dynamic storage is called.
+*/
+void km_init(void);
+
+/**
+** Name: km_dump
+**
+** Dump information about the free lists to the console. By default,
+** prints only the list sizes; if 'addrs' is true, also dumps the list
+** of page addresses; if 'all' is also true, dumps page addresses and
+** slice addresses.
+**
+** @param addrs Also dump page addresses
+** @param both Also dump slice addresses
+*/
+void km_dump(bool_t addrs, bool_t both);
+
+/*
+** Functions that manipulate free memory blocks.
+*/
+
+/**
+** Name: km_page_alloc
+**
+** Allocate a page of memory from the free list.
+**
+** @return a pointer to the beginning of the allocated page,
+** or NULL if no memory is available
+*/
+void *km_page_alloc(void);
+
+/**
+** Name: km_page_free
+**
+** Returns a memory block to the list of available blocks,
+** combining it with adjacent blocks if they're present.
+**
+** CRITICAL ASSUMPTION: multi-page blocks will be freed one page
+** at a time!
+**
+** @param[in] block Pointer to the page to be returned to the free list
+*/
+void km_page_free(void *block);
+
+/**
+** Name: km_slice_alloc
+**
+** Dynamically allocates a slice (1/4 of a page). If no
+** memory is available, we return NULL (unless ALLOC_FAIL_PANIC
+** was defined, in which case we panic).
+**
+** @return a pointer to the allocated slice
+*/
+void *km_slice_alloc(void);
+
+/**
+** Name: km_slice_free
+**
+** Returns a slice to the list of available slices.
+**
+** We make no attempt to merge slices, as they are independent
+** blocks of memory (unlike pages).
+**
+** @param[in] block Pointer to the slice (1/4 page) to be freed
+*/
+void km_slice_free(void *block);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/list.h b/kernel/old/include/list.h
new file mode 100644
index 0000000..0be11e9
--- /dev/null
+++ b/kernel/old/include/list.h
@@ -0,0 +1,68 @@
+/**
+** @file list.h
+**
+** @author Warren R. Carithers
+**
+** @brief Support for a basic linked list data type.
+**
+** This module provides a very basic linked list data structure.
+** A list can contain anything that has a pointer field in the first
+** four bytes; these routines assume those bytes contain a pointer to
+** the following entry in the list, whatever that may be.
+*/
+
+#ifndef LIST_H_
+#define LIST_H_
+
+#define KERNEL_SRC
+
+// standard types etc.
+#include <common.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Data types
+*/
+
+// The list structure
+typedef struct list_s {
+ struct list_s *next; // link to the successor
+} list_t;
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: list_add
+**
+** Add the supplied data to the beginning of the specified list.
+**
+** @param[in,out] list The address of a list_t variable
+** @param[in] data The data to prepend to the list
+*/
+void list_add(list_t *list, void *data);
+
+/**
+** Name: list_remove
+**
+** Remove the first entry from a linked list.
+**
+** @param[in,out] list The address of a list_t variable
+**
+** @return a pointer to the removed data, or NULL if the list was empty
+*/
+void *list_remove(list_t *list);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/params.h b/kernel/old/include/params.h
new file mode 100644
index 0000000..7a41e02
--- /dev/null
+++ b/kernel/old/include/params.h
@@ -0,0 +1,33 @@
+/**
+** @file params.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief System configuration settings
+**
+** This header file contains many of the "easily tunable" system
+** settings, such as clock rate, number of simultaneous user
+** processes, etc. This provides a sort of "one-stop shop" for
+** things that might be tweaked frequently.
+*/
+
+#ifndef PARAMS_H_
+#define PARAMS_H_
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// Upper bound on the number of simultaneous user-level
+// processes in the system (completely arbitrary)
+#define N_PROCS 25
+
+// Limit on the number of entries in argv[], INCLUDING
+// the trailing NULL pointer (also completely arbitrary)
+#define N_ARGS 10
+
+// Clock frequency (Hz)
+#define CLOCK_FREQ 1000
+#define TICKS_PER_MS 1
+
+#endif
diff --git a/kernel/old/include/procs.h b/kernel/old/include/procs.h
new file mode 100644
index 0000000..bc5b705
--- /dev/null
+++ b/kernel/old/include/procs.h
@@ -0,0 +1,457 @@
+/*
+** @file procs.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Process-related declarations
+*/
+
+#ifndef PROCS_H_
+#define PROCS_H_
+
+#include <common.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Types
+*/
+
+/*
+** Process states
+*/
+enum state_e {
+ // pre-viable
+ STATE_UNUSED = 0,
+ STATE_NEW,
+ // runnable
+ STATE_READY,
+ STATE_RUNNING,
+ // runnable, but waiting for some event
+ STATE_SLEEPING,
+ STATE_BLOCKED,
+ STATE_WAITING,
+ // no longer runnable
+ STATE_KILLED,
+ STATE_ZOMBIE
+ // sentinel value
+ ,
+ N_STATES
+};
+
+// these may be handy for checking general conditions of processes
+// they depend on the order of the state names in the enum!
+#define FIRST_VIABLE STATE_READY
+#define FIRST_BLOCKED STATE_SLEEPING
+#define LAST_VIABLE STATE_WAITING
+
+/*
+** Process priorities are defined in <defs.h>
+*/
+
+/*
+** Quantum lengths - values are number of clock ticks
+*/
+enum quantum_e { QUANTUM_SHORT = 1, QUANTUM_STANDARD = 3, QUANTUM_LONG = 5 };
+
+/*
+** PID-related definitions
+*/
+#define PID_INIT 1
+#define FIRST_USER_PID 2
+
+/*
+** Process context structure
+**
+** NOTE: the order of data members here depends on the
+** register save code in isr_stubs.S!!!!
+**
+** This will be at the top of the user stack when we enter
+** an ISR. In the case of a system call, it will be followed
+** by the return address and the system call parameters.
+*/
+
+typedef struct context_s {
+ uint32_t ss; // pushed by isr_save
+ uint32_t gs;
+ uint32_t fs;
+ uint32_t es;
+ uint32_t ds;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t vector;
+ uint32_t code; // pushed by isr_save or the hardware
+ uint32_t eip; // pushed by the hardware
+ uint32_t cs;
+ uint32_t eflags;
+} context_t;
+
+#define SZ_CONTEXT sizeof(context_t)
+
+/*
+** program section information for user processes
+*/
+
+typedef struct section_s {
+ uint_t length; // length, in some units
+ uint_t addr; // location, in some units
+} section_t;
+
+// note: these correspond to the PT_LOAD sections found in
+// an ELF file, not necessarily to text/data/bss
+#define SECT_L1 0
+#define SECT_L2 1
+#define SECT_L3 2
+#define SECT_STACK 3
+
+// total number of section table entries in our PCB
+#define N_SECTS 4
+// number of those that can be loaded from an ELF module
+#define N_LOADABLE 3
+
+/*
+** The process control block
+**
+** Fields are ordered by size to avoid padding
+**
+** Currently, this is 72 bytes long. It could be reduced to 64 (2^6)
+** bytes by making the last four fields uint16_t types; that would
+** divide nicely into 1024 bytes, giving 16 PCBs per 1/4 page of memory.
+*/
+
+typedef struct pcb_s {
+ // four-byte fields
+ // start with these four bytes, for easy access in assembly
+ context_t *context; // pointer to context save area on stack
+
+ // VM information
+ pde_t *pdir; // page directory for this process
+ section_t sects[N_SECTS]; // per-section memory information
+
+ // queue linkage
+ struct pcb_s *next; // next PCB in queue
+
+ // process state information
+ struct pcb_s *parent; // pointer to PCB of our parent process
+ uint32_t wakeup; // wakeup time, for sleeping processes
+ int32_t exit_status; // termination status, for parent's use
+
+ // these things may not need to be four bytes
+ uint_t pid; // PID of this process
+ enum state_e state; // process' current state
+ enum priority_e priority; // process priority level
+ uint_t ticks; // remaining ticks in this time slice
+
+} pcb_t;
+
+#define SZ_PCB sizeof(pcb_t)
+
+/*
+** PCB queue structure (opaque to the rest of the kernel)
+*/
+typedef struct pcb_queue_s *pcb_queue_t;
+
+/*
+** Queue ordering methods
+*/
+enum pcb_queue_order_e {
+ O_FIFO,
+ O_PRIO,
+ O_PID,
+ O_WAKEUP
+ // sentinel
+ ,
+ N_ORDERINGS
+};
+#define O_FIRST_STYLE O_FIFO
+#define O_LAST_STYLE O_WAKEUP
+
+/*
+** Globals
+*/
+
+// public-facing queue handles
+extern pcb_queue_t pcb_freelist;
+extern pcb_queue_t ready;
+extern pcb_queue_t waiting;
+extern pcb_queue_t sleeping;
+extern pcb_queue_t zombie;
+extern pcb_queue_t sioread;
+
+// pointer to the currently-running process
+extern pcb_t *current;
+
+// the process table
+extern pcb_t ptable[N_PROCS];
+
+// next available PID
+extern uint_t next_pid;
+
+// pointer to the PCB for the 'init' process
+extern pcb_t *init_pcb;
+
+// table of state name strings
+extern const char state_str[N_STATES][4];
+
+// table of priority name strings
+extern const char prio_str[N_PRIOS][5];
+
+// table of queue ordering name strings
+extern const char ord_str[N_ORDERINGS][5];
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: pcb_init
+**
+** Initialization for the Process module.
+*/
+void pcb_init(void);
+
+/**
+** Name: pcb_alloc
+**
+** Allocate a PCB from the list of free PCBs.
+**
+** @param pcb Pointer to a pcb_t * where the PCB pointer will be returned.
+**
+** @return status of the allocation attempt
+*/
+int pcb_alloc(pcb_t **pcb);
+
+/**
+** Name: pcb_free
+**
+** Return a PCB to the list of free PCBs.
+**
+** @param pcb Pointer to the PCB to be deallocated.
+*/
+void pcb_free(pcb_t *pcb);
+
+/**
+** Name: pcb_zombify
+**
+** Turn the indicated process into a Zombie. This function
+** does most of the real work for exit() and kill() calls.
+** Is also called from the scheduler and dispatcher.
+**
+** @param pcb Pointer to the newly-undead PCB
+*/
+void pcb_zombify(register pcb_t *victim);
+
+/**
+** Name: pcb_cleanup
+**
+** Reclaim a process' data structures
+**
+** @param pcb The PCB to reclaim
+*/
+void pcb_cleanup(pcb_t *pcb);
+
+/**
+** Name: pcb_find_pid
+**
+** Locate the PCB for the process with the specified PID
+**
+** @param pid The PID to be located
+**
+** @return Pointer to the PCB, or NULL
+*/
+pcb_t *pcb_find_pid(uint_t pid);
+
+/**
+** Name: pcb_find_ppid
+**
+** Locate the PCB for the process with the specified parent
+**
+** @param pid The PID to be located
+**
+** @return Pointer to the PCB, or NULL
+*/
+pcb_t *pcb_find_ppid(uint_t pid);
+
+/**
+** Name: pcb_queue_reset
+**
+** Initialize a PCB queue.
+**
+** @param queue[out] The queue to be initialized
+** @param order[in] The desired ordering for the queue
+**
+** @return status of the init request
+*/
+int pcb_queue_reset(pcb_queue_t queue, enum pcb_queue_order_e style);
+
+/**
+** Name: pcb_queue_empty
+**
+** Determine whether a queue is empty. Essentially just a wrapper
+** for the PCB_QUEUE_EMPTY() macro, for use outside this module.
+**
+** @param[in] queue The queue to check
+**
+** @return true if the queue is empty, else false
+*/
+bool_t pcb_queue_empty(pcb_queue_t queue);
+
+/**
+** Name: pcb_queue_length
+**
+** Return the count of elements in the specified queue.
+**
+** @param[in] queue The queue to check
+**
+** @return the count (0 if the queue is empty)
+*/
+uint_t pcb_queue_length(const pcb_queue_t queue);
+
+/**
+** Name: pcb_queue_insert
+**
+** Inserts a PCB into the indicated queue.
+**
+** @param queue[in,out] The queue to be used
+** @param pcb[in] The PCB to be inserted
+**
+** @return status of the insertion request
+*/
+int pcb_queue_insert(pcb_queue_t queue, pcb_t *pcb);
+
+/**
+** Name: pcb_queue_peek
+**
+** Return the first PCB from the indicated queue, but don't
+** remove it from the queue
+**
+** @param queue[in] The queue to be used
+**
+** @return the PCB pointer, or NULL if the queue is empty
+*/
+pcb_t *pcb_queue_peek(const pcb_queue_t queue);
+
+/**
+** Name: pcb_queue_remove
+**
+** Remove the first PCB from the indicated queue.
+**
+** @param queue[in,out] The queue to be used
+** @param pcb[out] Pointer to where the PCB pointer will be saved
+**
+** @return status of the removal request
+*/
+int pcb_queue_remove(pcb_queue_t queue, pcb_t **pcb);
+
+/**
+** Name: pcb_queue_remove_this
+**
+** Remove the specified PCB from the indicated queue.
+**
+** @param queue[in,out] The queue to be used
+** @param pcb[in] Pointer to the PCB to be removed
+**
+** @return status of the removal request
+*/
+int pcb_queue_remove_this(pcb_queue_t queue, pcb_t *pcb);
+
+/*
+** Scheduler routines
+*/
+
+/**
+** schedule(pcb)
+**
+** Schedule the supplied process
+**
+** @param pcb Pointer to the PCB of the process to be scheduled
+*/
+void schedule(pcb_t *pcb);
+
+/**
+** dispatch()
+**
+** Select the next process to receive the CPU
+*/
+void dispatch(void);
+
+/*
+** Debugging/tracing routines
+*/
+
+/**
+** Name: ctx_dump
+**
+** Dumps the contents of this process context to the console
+**
+** @param msg[in] An optional message to print before the dump
+** @param c[in] The context to dump out
+*/
+void ctx_dump(const char *msg, register context_t *c);
+
+/**
+** Name: ctx_dump_all
+**
+** dump the process context for all active processes
+**
+** @param msg[in] Optional message to print
+*/
+void ctx_dump_all(const char *msg);
+
+/**
+** Name: pcb_dump
+**
+** Dumps the contents of this PCB to the console
+**
+** @param msg[in] An optional message to print before the dump
+** @param p[in] The PCB to dump
+** @param all[in] Dump all the contents?
+*/
+void pcb_dump(const char *msg, register pcb_t *p, bool_t all);
+
+/**
+** Name: pcb_queue_dump
+**
+** Dump the contents of the specified queue to the console
+**
+** @param msg[in] An optional message to print before the dump
+** @param queue[in] The queue to dump
+** @param contents[in] Also dump (some) contents?
+*/
+void pcb_queue_dump(const char *msg, pcb_queue_t queue, bool_t contents);
+
+/**
+** Name: ptable_dump
+**
+** dump the contents of the "active processes" table
+**
+** @param msg[in] Optional message to print
+** @param all[in] Dump all or only part of the relevant data
+*/
+void ptable_dump(const char *msg, bool_t all);
+
+/**
+** Name: ptable_dump_counts
+**
+** Prints basic information about the process table (number of
+** entries, number with each process state, etc.).
+*/
+void ptable_dump_counts(void);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/serial.h b/kernel/old/include/serial.h
new file mode 100644
index 0000000..20bf192
--- /dev/null
+++ b/kernel/old/include/serial.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include <stdint.h>
diff --git a/kernel/old/include/sio.h b/kernel/old/include/sio.h
new file mode 100644
index 0000000..629fda2
--- /dev/null
+++ b/kernel/old/include/sio.h
@@ -0,0 +1,168 @@
+/**
+** @file sio.h
+**
+** @author Warren R. Carithers
+**
+** @brief SIO definitions
+*/
+
+#ifndef SIO_H_
+#define SIO_H_
+
+// compatibility definitions
+#include <compat.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// sio interrupt settings
+
+#define SIO_TX 0x01
+#define SIO_RX 0x02
+#define SIO_BOTH (SIO_TX | SIO_RX)
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+#include <common.h>
+
+#include <procs.h>
+
+/*
+** PUBLIC GLOBAL VARIABLES
+*/
+
+// queue for read-blocked processes
+extern QTYPE QNAME;
+
+/*
+** PUBLIC FUNCTIONS
+*/
+
+/**
+** sio_init()
+**
+** Initialize the UART chip.
+*/
+void sio_init(void);
+
+/**
+** sio_enable()
+**
+** Enable SIO interrupts
+**
+** usage: uint8_t old = sio_enable( uint8_t which )
+**
+** @param which Bit mask indicating which interrupt(s) to enable
+**
+** @return the prior IER setting
+*/
+uint8_t sio_enable(uint8_t which);
+
+/**
+** sio_disable()
+**
+** Disable SIO interrupts
+**
+** usage: uint8_t old = sio_disable( uint8_t which )
+**
+** @param which Bit mask indicating which interrupt(s) to disable
+**
+** @return the prior IER setting
+*/
+uint8_t sio_disable(uint8_t which);
+
+/**
+** sio_inq_length()
+**
+** Get the input queue length
+**
+** usage: int num = sio_inq_length()
+**
+** @return the count of characters still in the input queue
+*/
+int sio_inq_length(void);
+
+/**
+** sio_readc()
+**
+** Get the next input character
+**
+** usage: int ch = sio_readc()
+**
+** @return the next character, or -1 if no character is available
+*/
+int sio_readc(void);
+
+/**
+** sio_read()
+**
+** Read the entire input buffer into a user buffer of a specified size
+**
+** usage: int num = sio_read( char *buffer, int length )
+**
+** @param buf The destination buffer
+** @param length Length of the buffer
+**
+** @return the number of bytes copied, or 0 if no characters were available
+*/
+int sio_read(char *buffer, int length);
+
+/**
+** sio_writec( ch )
+**
+** Write a character to the serial output
+**
+** usage: sio_writec( int ch )
+**
+** @param ch Character to be written (in the low-order 8 bits)
+*/
+void sio_writec(int ch);
+
+/**
+** sio_write( ch )
+**
+** Write a buffer of characters to the serial output
+**
+** usage: int num = sio_write( const char *buffer, int length )
+**
+** @param buffer Buffer containing characters to write
+** @param length Number of characters to write
+**
+** @return the number of characters copied into the SIO output buffer
+*/
+int sio_write(const char *buffer, int length);
+
+/**
+** sio_puts( buf )
+**
+** Write a NUL-terminated buffer of characters to the serial output
+**
+** usage: n = sio_puts( const char *buffer );
+**
+** @param buffer The buffer containing a NUL-terminated string
+**
+** @return the count of bytes transferred
+*/
+int sio_puts(const char *buffer);
+
+/**
+** sio_dump( full )
+**
+** Dump the contents of the SIO buffers to the console
+**
+** usage: sio_dump(true) or sio_dump(false)
+**
+** @param full Boolean indicating whether or not a "full" dump
+** is being requested (which includes the contents
+** of the queues)
+*/
+void sio_dump(bool_t full);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/support.h b/kernel/old/include/support.h
new file mode 100644
index 0000000..ac75a64
--- /dev/null
+++ b/kernel/old/include/support.h
@@ -0,0 +1,86 @@
+/**
+** SCCS ID: @(#)support.h 2.3 1/22/25
+**
+** @file support.h
+**
+** @author K. Reek
+** @author Warren R. Carithers
+**
+** Declarations for functions provided in support.c, and
+** some hardware characteristics needed in the initialization.
+**
+*/
+
+#ifndef SUPPORT_H
+#define SUPPORT_H
+
+/*
+** Delay values
+**
+** Notes: The parameter to the delay() function is ambiguous; it
+** purports to indicate a delay length, but that isn't really tied
+** to any real-world time measurement.
+**
+** On the original systems we used (dual 500MHz Intel P3 CPUs), each
+** "unit" was approximately one tenth of a second, so delay(10) would
+** delay for about one second.
+**
+** On the current machines (Intel Core i5-7500), delay(100) is about
+** 2.5 seconds, so each "unit" is roughly 0.025 seconds.
+**
+** Ultimately, just remember that THESE VALUES ARE APPROXIMATE AT BEST.
+*/
+#define DELAY_1_SEC 40
+#define DELAY_1_25_SEC 50
+#define DELAY_2_SEC 80
+#define DELAY_2_5_SEC 100
+#define DELAY_3_SEC 120
+#define DELAY_5_SEC 200
+#define DELAY_7_SEC 280
+#define DELAY_10_SEC 400
+
+#ifndef ASM_SRC
+/**
+** panic
+**
+** Called when we find an unrecoverable error, this routine disables
+** interrupts, prints a description of the error and then goes into a
+** hard loop to prevent any further processing.
+**
+** @param reason NUL-terminated message to be printed.
+*/
+void panic(char *reason);
+
+/**
+** init_interrupts
+**
+** (Re)initilizes the interrupt system. This includes initializing the
+** IDT and the PIC. It is up to the user to enable processor interrupts
+** when they're ready.
+*/
+void init_interrupts(void);
+
+/*
+** install_isr
+**
+** Installs a second-level handler for a specific interrupt. Returns the
+** previously-installed handler for reinstallation (if desired).
+**
+** @param vector the interrupt vector number
+** @param handler the second-stage ISR function to be called by the stub
+**
+** @return a pointer to the previously-registered ISR
+*/
+void (*install_isr(int vector, void (*handler)(int, int)))(int, int);
+
+/*
+** Name: delay
+**
+** See the comment above about the relative accuracy of the 'length'
+** parameter.
+*/
+void delay(int length);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/syscalls.h b/kernel/old/include/syscalls.h
new file mode 100644
index 0000000..27392a1
--- /dev/null
+++ b/kernel/old/include/syscalls.h
@@ -0,0 +1,80 @@
+/**
+** @file syscalls.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief System call declarations
+*/
+
+#ifndef SYSCALLS_H_
+#define SYSCALLS_H_
+
+#include <common.h>
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+/*
+** system call codes
+**
+** these are used in the user-level C library stub functions,
+** and are defined here as CPP macros instead of as an enum
+** so that they can be used from assembly
+*/
+
+#define SYS_exit 0
+#define SYS_waitpid 1
+#define SYS_fork 2
+#define SYS_exec 3
+#define SYS_read 4
+#define SYS_write 5
+#define SYS_getpid 6
+#define SYS_getppid 7
+#define SYS_gettime 8
+#define SYS_getprio 9
+#define SYS_setprio 10
+#define SYS_kill 11
+#define SYS_sleep 12
+
+// UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED!
+#define N_SYSCALLS 13
+
+// dummy system call code for testing our ISR
+#define SYS_bogus 0xbad
+
+// interrupt vector entry for system calls
+#define VEC_SYSCALL 0x80
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Types
+*/
+
+/*
+** Globals
+*/
+
+/*
+** Prototypes
+*/
+
+#ifdef KERNEL_SRC
+
+/**
+** Name: sys_init
+**
+** Syscall module initialization routine
+*/
+void sys_init(void);
+
+#endif /* KERNEL_SRC */
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/types.h b/kernel/old/include/types.h
new file mode 100644
index 0000000..9435954
--- /dev/null
+++ b/kernel/old/include/types.h
@@ -0,0 +1,13 @@
+#ifndef TYPES_H_
+#define TYPES_H_
+#ifndef ASM_SRC
+
+#ifdef KERNEL_SRC
+// we define these here instead of in vm.h in order to get around a
+// nasty chick/egg dependency between procs.h and vm.h
+typedef uint32_t pde_t; // page directory entry
+typedef uint32_t pte_t; // page table entry
+#endif /* KERNEL_SRC */
+
+#endif
+#endif
diff --git a/kernel/old/include/user.h b/kernel/old/include/user.h
new file mode 100644
index 0000000..672f916
--- /dev/null
+++ b/kernel/old/include/user.h
@@ -0,0 +1,139 @@
+/**
+** @file user.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Declarations of user-level code management routines
+*/
+
+#ifndef USER_H_
+#define USER_H_
+
+#include <common.h>
+
+#include <procs.h>
+#include <x86/arch.h>
+
+// default value for EFLAGS in new processes
+#define DEFAULT_EFLAGS (EFL_MB1 | EFL_IF)
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+/*
+** Types
+*/
+
+/*
+** Blob file organization
+**
+** The file begins with a four-byte magic number and a four-byte integer
+** indicating the number of ELF files contained in the blob. This is
+** followed by an array of 32-byte file table entries, and then the contents
+** of the ELF files in the order they appear in the program file table.
+**
+** Bytes Contents
+** ----- ----------------------------
+** 0 - 3 File magic number ("BLB\0")
+** 4 - 7 Number of ELF files in blob ("n")
+** 8 - n*32+8 Program file table
+** n*32+9 - ? ELF file contents
+**
+** Each program file table entry contains the following information:
+**
+** name File name (up to 19 characters long)
+** offset Byte offset to the ELF header for this file
+** size Size of this ELF file, in bytes
+** flags Flags related to this file
+*/
+
+// user program blob header
+typedef struct header_s {
+ char magic[4];
+ uint32_t num;
+} header_t;
+
+// length of the file name field
+#define NAMELEN 20
+
+// program descriptor
+typedef struct prog_s {
+ char name[NAMELEN]; // truncated name (15 chars)
+ uint32_t offset; // offset from the beginning of the blob
+ uint32_t size; // size of this ELF module
+ uint32_t flags; // miscellaneous flags
+} prog_t;
+
+/*
+** Globals
+*/
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: user_init
+**
+** Initializes the user support module.
+*/
+void user_init(void);
+
+/**
+** Name: user_locate
+**
+** Locates a user program in the user code archive.
+**
+** @param what The ID of the user program to find
+**
+** @return pointer to the program table entry in the code archive, or NULL
+*/
+prog_t *user_locate(uint_t what);
+
+/**
+** Name: user_duplicate
+**
+** Duplicates the memory setup for an existing process.
+**
+** @param new The PCB for the new copy of the program
+** @param old The PCB for the existing the program
+**
+** @return the status of the duplicate attempt
+*/
+int user_duplicate(pcb_t *new, pcb_t *old);
+
+/**
+** Name: user_load
+**
+** Loads a user program from the user code archive into memory.
+** Allocates all needed frames and sets up the VM tables.
+**
+** @param prog A pointer to the program table entry to be loaded
+** @param pcb The PCB for the program being loaded
+** @param args The argument vector for the program
+** @param sys Is the argument vector from kernel code?
+**
+** @return the status of the load attempt
+*/
+int user_load(prog_t *prog, pcb_t *pcb, const char **args, bool_t sys);
+
+/**
+** Name: user_cleanup
+**
+** "Unloads" a user program. Deallocates all memory frames and
+** cleans up the VM structures.
+**
+** @param pcb The PCB of the program to be cleaned up
+*/
+void user_cleanup(pcb_t *pcb);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/vm.h b/kernel/old/include/vm.h
new file mode 100644
index 0000000..dc12568
--- /dev/null
+++ b/kernel/old/include/vm.h
@@ -0,0 +1,501 @@
+/**
+** @file vm.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Virtual memory-related declarations.
+*/
+
+#ifndef VM_H_
+#define VM_H_
+
+#include <defs.h>
+#include <types.h>
+
+#include <procs.h>
+
+/*
+** VM layout of the system
+**
+** User processes use the first 4MB of the 32-bit address space; see the
+** next comment for details.
+**
+** Kernel virtual addresses are in the "higher half" range, beginning
+** at 0x80000000. We define our mapping such that virtual address
+** 0x8nnnnnnn maps to physical address 0x0nnnnnnn, so converting between
+** the two is trivial.
+*/
+
+/*
+** VM layout of process' address space
+**
+** Processes are limited to the first 4MB of the 32-bit address space:
+**
+** Address Range Contents
+** ======================= ================================
+** 0x00000000 - 0x00000fff page 0 is inaccessible
+** 0x00001000 - 0x000..fff text occupies pages 1 - N
+** 0x000..000 - 0x000..fff data occupies pages N+1 - N+d
+** 0x000..000 - 0x000..fff bss occupies pages N+d+1 - N+d+b
+** 0x000..000 - 0x003fdfff unusable
+** 0x003fe000 - 0x003fffff stack occupies last two pages
+**
+** This gives us the following page table structure:
+**
+** Page directory:
+** Entries Contents
+** ======== ==============================
+** 0 point to PMT for address space
+** 1 - 1023 invalid
+**
+** Page map table:
+** Entries Contents
+** ======== ==============================
+** 0 invalid
+** 1 - N text frames
+** N+1 - N+d data frames
+** N+d+1 - N+d+b bss frames
+** N+d+b+1 - 1021 invalid
+** 1022 - 1023 stack frames
+*/
+
+/*
+** General (C and/or assembly) definitions
+*/
+
+// user virtual addresses
+#define USER_BASE 0x00000000
+#define USER_MAX 0x003fffff
+#define USER_TEXT 0x00001000
+#define USER_STACK 0x003fe000
+#define USER_STACK_P1 USER_STACK
+#define USER_STACK_P2 0x003ff000
+#define USER_STK_END 0x00400000
+
+// how to find the addresses of the stack pages in the VM hierarchy
+// user address space is the first 4MB of virtual memory
+#define USER_PDE 0
+// the stack occupies this range of pages in the user address space
+#define USER_STK_FIRST_PTE 1022
+#define USER_STK_LAST_PTE 1023
+
+// some important memory addresses
+#define KERN_BASE 0x80000000 // start of "kernel" memory
+#define EXT_BASE 0x00100000 // start of "extended" memory (1MB)
+#define DEV_BASE 0xfe000000 // "device" memory
+#define PHYS_TOP 0x3fffffff // last usable physical address (1GB - 1)
+
+// where the kernel actually lives
+#define KERN_PLINK 0x00010000
+#define KERN_VLINK (KERN_BASE + KERN_PLINK)
+
+// number of entries in a page directory or page table
+#define N_PDE 1024
+#define N_PTE 1024
+
+// index field shift counts and masks
+#define PDIX_SHIFT 22
+#define PTIX_SHIFT 12
+#define PIX2I_MASK 0x3ff
+
+// physical/virtual converters that don't use casting
+// (usable from anywhere)
+#define V2PNC(a) ((a) - KERN_BASE)
+#define P2VNC(a) ((a) + KERN_BASE)
+
+// page-size address rounding macros
+#define SZ_PG_M1 MOD4K_BITS
+#define SZ_PG_MASK MOD4K_MASK
+#define PGUP(a) (((a) + SZ_PG_M1) & SZ_PG_MASK)
+#define PGDOWN(a) ((a) & SZ_PG_MASK)
+
+// page directory entry bit fields
+#define PDE_P 0x00000001 // 1 = present
+#define PDE_RW 0x00000002 // 1 = writable
+#define PDE_US 0x00000004 // 1 = user and system usable
+#define PDE_PWT 0x00000008 // cache: 1 = write-through
+#define PDE_PCD 0x00000010 // cache: 1 = disabled
+#define PDE_A 0x00000020 // accessed
+#define PDE_D 0x00000040 // dirty (4MB pages)
+#define PDE_AVL1 0x00000040 // ignored (4KB pages)
+#define PDE_PS 0x00000080 // 1 = 4MB page size
+#define PDE_G 0x00000100 // global
+#define PDE_AVL2 0x00000e00 // ignored
+#define PDE_PAT 0x00001000 // (4MB pages) use page attribute table
+#define PDE_PTA 0xfffff000 // page table address field (4KB pages)
+#define PDE_FA 0xffc00000 // frame address field (4MB pages)
+
+// page table entry bit fields
+#define PTE_P 0x00000001 // present
+#define PTE_RW 0x00000002 // 1 = writable
+#define PTE_US 0x00000004 // 1 = user and system usable
+#define PTE_PWT 0x00000008 // cache: 1 = write-through
+#define PTE_PCD 0x00000010 // cache: 1 = disabled
+#define PTE_A 0x00000020 // accessed
+#define PTE_D 0x00000040 // dirty
+#define PTE_PAT 0x00000080 // use page attribute table
+#define PTE_G 0x00000100 // global
+#define PTE_AVL2 0x00000e00 // ignored
+#define PTE_FA 0xfffff000 // frame address field
+
+// error code bit assignments for page faults
+#define PFLT_P 0x00000001
+#define PFLT_W 0x00000002
+#define PFLT_US 0x00000004
+#define PFLT_RSVD 0x00000008
+#define PFLT_ID 0x00000010
+#define PFLT_PK 0x00000020
+#define PFLT_SS 0x00000040
+#define PFLT_HLAT 0x00000080
+#define PFLT_SGX 0x00008000
+#define PFLT_UNUSED 0xffff7f00
+
+#ifndef ASM_SRC
+
+/*
+** Start of C-only definitions
+*/
+
+// physical/virtual converters that do use casting
+// (not usable from assembly)
+#define V2P(a) (((uint32_t)(a)) - KERN_BASE)
+#define P2V(a) (((uint32_t)(a)) + KERN_BASE)
+
+// create a pde/pte from an integer frame number and permission bits
+#define MKPDE(f, p) ((pde_t)(TO_FRAME((f)) | (p)))
+#define MKPTE(f, p) ((pte_t)(TO_FRAME((f)) | (p)))
+
+// is a PDE/PTE present?
+// (P bit is in the same place in both)
+#define IS_PRESENT(entry) (((entry) & PDE_P) != 0)
+
+// is a PDE a 4MB page entry?
+#define IS_LARGE(pde) (((pde) & PDE_PS) != 0)
+
+// is this entry "system only" or "system and user"?
+#define IS_SYSTEM(entry) (((entry) & PDE_US) == 0)
+#define IS_USER(entry) (((entry) & PDE_US) != 0)
+
+// low-order nine bits of PDEs and PTEs hold "permission" flag bits
+#define PERMS_MASK MOD4K_BITS
+
+// 4KB frame numbers are 20 bits wide
+#define FRAME_4K_SHIFT 12
+#define FRAME2I_4K_MASK 0x000fffff
+#define TO_4KFRAME(n) (((n) & FRAME2I_4K_MASK) << FRAME_4K_SHIFT)
+#define GET_4KFRAME(n) (((n) >> FRAME_4K_SHIFT) & FRAME2I_4K_MASK)
+#define PDE_4K_ADDR(n) ((n) & MOD4K_MASK)
+#define PTE_4K_ADDR(n) ((n) & MOD4K_MASK)
+
+// 4MB frame numbers are 10 bits wide
+#define FRAME_4M_SHIFT 22
+#define FRAME2I_4M_MASK 0x000003ff
+#define TO_4MFRAME(n) (((n) & FRAME2I_4M_MASK) << FRAME_4M_SHIFT)
+#define GET_4MFRAME(n) (((n) >> FRAME_4M_SHIFT) & FRAME2I_4M_MASK)
+#define PDE_4M_ADDR(n) ((n) & MOD4M_MASK)
+#define PTE_4M_ADDR(n) ((n) & MOD4M_MASK)
+
+// extract the PMT address or frame address from a table entry
+// PDEs could point to 4MB pages, or 4KB PMTs
+#define PDE_ADDR(p) \
+ (IS_LARGE(p) ? (((uint32_t)p) & PDE_FA) : (((uint32_t)p) & PDE_PTA))
+// PTEs always point to 4KB pages
+#define PTE_ADDR(p) (((uint32_t)(p)) & PTE_FA)
+// everything has nine bits of permission flags
+#define PERMS(p) (((uint32_t)(p)) & PERMS_MASK)
+
+// extract the table indices from a 32-bit VA
+#define PDIX(v) ((((uint32_t)(v)) >> PDIX_SHIFT) & PIX2I_MASK)
+#define PTIX(v) ((((uint32_t)(v)) >> PTIX_SHIFT) & PIX2I_MASK)
+
+// extract the byte offset from a 32-bit VA
+#define OFFSET_4K(v) (((uint32_t)(v)) & MOD4K_BITS)
+#define OFFSET_4M(v) (((uint32_t)(v)) & MOD4M_BITS)
+
+/*
+** Types
+*/
+
+// page directory entries
+
+// as a 32-bit word, in types.h
+// typedef uint32_t pde_t;
+
+// PDE for 4KB pages
+typedef struct pdek_s {
+ uint_t p : 1; // 0: present
+ uint_t rw : 1; // 1: writable
+ uint_t us : 1; // 2: user/supervisor
+ uint_t pwt : 1; // 3: cache write-through
+ uint_t pcd : 1; // 4: cache disable
+ uint_t a : 1; // 5: accessed
+ uint_t avl1 : 1; // 6: ignored (available)
+ uint_t ps : 1; // 7: page size (must be 0)
+ uint_t avl2 : 4; // 11-8: ignored (available)
+ uint_t fa : 20; // 31-12: frame address
+} pdek_f_t;
+
+// PDE for 4MB pages
+typedef struct pdem_s {
+ uint_t p : 1; // 0: present
+ uint_t rw : 1; // 1: writable
+ uint_t us : 1; // 2: user/supervisor
+ uint_t pwt : 1; // 3: cache write-through
+ uint_t pcd : 1; // 4: cache disable
+ uint_t a : 1; // 5: accessed
+ uint_t d : 1; // 6: dirty
+ uint_t ps : 1; // 7: page size (must be 1)
+ uint_t g : 1; // 8: global
+ uint_t avl : 3; // 11-9: ignored (available)
+ uint_t pat : 1; // 12: page attribute table in use
+ uint_t fa2 : 4; // 16-13: bits 35-32 of frame address (36-bit addrs)
+ uint_t rsv : 5; // 21-17: reserved - must be zero
+ uint_t fa : 10; // 31-22: bits 31-22 of frame address
+} pdem_f_t;
+
+// page table entries
+
+// as a 32-bit word, in types.h
+// typedef uint32_t pte_t;
+
+// broken out into fields
+typedef struct pte_s {
+ uint_t p : 1; // 0: present
+ uint_t rw : 1; // 1: writable
+ uint_t us : 1; // 2: user/supervisor
+ uint_t pwt : 1; // 3: cache write-through
+ uint_t pcd : 1; // 4: cache disable
+ uint_t a : 1; // 5: accessed
+ uint_t d : 1; // 6: dirty
+ uint_t pat : 1; // 7: page attribute table in use
+ uint_t g : 1; // 8: global
+ uint_t avl : 3; // 11-9: ignored (available)
+ uint_t fa : 20; // 31-12: frame address
+} ptef_t;
+
+// page fault error code bits
+// comment: meaning when 1 / meaning when 0
+struct pfec_s {
+ uint_t p : 1; // page-level protection violation / !present
+ uint_t w : 1; // write / read
+ uint_t us : 1; // user-mode access / supervisor-mode access
+ uint_t rsvd : 1; // reserved bit violation / not
+ uint_t id : 1; // instruction fetch / data fetch
+ uint_t pk : 1; // protection-key violation / !pk
+ uint_t ss : 1; // shadow stack access / !ss
+ uint_t hlat : 1; // HLAT paging / ordinary paging or access rights
+ uint_t xtr1 : 7; // unused
+ uint_t sgz : 1; // SGX-specific access control violation / !SGX
+ uint_t xtr2 : 16; // more unused
+};
+
+typedef union pfec_u {
+ uint32_t u;
+ struct pfec_s s;
+} pfec_t;
+
+// Mapping descriptor for VA::PA mappings
+typedef struct mapping_t {
+ uint32_t va_start; // starting virtual address for this range
+ uint32_t pa_start; // first physical address in the range
+ uint32_t pa_end; // last physical address in the range
+ uint32_t perm; // access control
+} mapping_t;
+
+// Modes for dumping out page hierarchies
+enum vmmode_e {
+ Simple = 0, // just count 'present' entries at each level
+ OneLevel, // top-level only: count entries, decode 'present'
+ TwoLevel, // count entries & decode at each level
+ Full // ??? in case we need more?
+ // sentinel
+ ,
+ N_VMMODES
+};
+
+/*
+** Globals
+*/
+
+// created page directory for the kernel
+extern pde_t *kpdir;
+
+/*
+** Prototypes
+*/
+
+/**
+** Name: vm_init
+**
+** Initialize the VM module
+**
+** Note: should not be called until after the memory free list has
+** been set up.
+*/
+void vm_init(void);
+
+/**
+** Name: vm_uva2kva
+**
+** Convert a user VA into a kernel address. Works for all addresses -
+** if the address is a page address, the low-order nine bits will be
+** zeroes; otherwise, they is the offset into the page, which is
+** unchanged within the address spaces.
+**
+** @param pdir Pointer to the page directory to examine
+** @param va Virtual address to check
+*/
+void *vm_uva2kva(pde_t *pdir, void *va);
+
+/**
+** Name: vm_pagedup
+**
+** Duplicate a page of memory
+**
+** @param old Pointer to the first byte of a page
+**
+** @return a pointer to the new, duplicate page, or NULL
+*/
+void *vm_pagedup(void *old);
+
+/**
+** Name: vm_pdedup
+**
+** Duplicate a page directory entry
+**
+** @param entry The entry to be duplicated
+**
+** @return the new entry, or -1 on error.
+*/
+pde_t vm_pdedup(pde_t entry);
+
+/**
+** Name: vm_ptdup
+**
+** Duplicate a page directory entry
+**
+** @param dst Pointer to where the duplicate should go
+** @param curr Pointer to the entry to be duplicated
+**
+** @return true on success, else false
+*/
+bool_t vm_ptdup(pde_t *dst, pde_t *curr);
+
+/**
+** Name: vm_getpte
+**
+** Return the address of the PTE corresponding to the virtual address
+** 'va' within the address space controlled by 'pgdir'. If there is no
+** page table for that VA and 'alloc' is true, create the necessary
+** page table entries.
+**
+** @param pdir Pointer to the page directory to be searched
+** @param va The virtual address we're looking for
+** @param alloc Should we allocate a page table if there isn't one?
+**
+** @return A pointer to the page table entry for this VA, or NULL
+*/
+pte_t *vm_getpte(pde_t *pdir, const void *va, bool_t alloc);
+
+/**
+** Name: vm_mkkvm
+**
+** Create the kernel's page table hierarchy
+*/
+pde_t *vm_mkkvm(void);
+
+/**
+** Name: vm_mkuvm
+**
+** Create the page table hierarchy for a user process
+*/
+pde_t *vm_mkuvm(void);
+
+/**
+** Name: vm_set_kvm
+**
+** Switch the page table register to the kernel's page directory
+*/
+void vm_set_kvm(void);
+
+/**
+** Name: vm_set_uvm
+**
+** Switch the page table register to the page directory for a user process.
+**
+** @param p The PCB of the user process
+*/
+void vm_set_uvm(pcb_t *p);
+
+/**
+** Name: vm_add
+**
+** Add pages to the page hierarchy for a process, copying data into
+** them if necessary.
+**
+** @param pdir Pointer to the page directory to modify
+** @param wr "Writable" flag for the PTE
+** @param sys "System" flag for the PTE
+** @param va Starting VA of the range
+** @param size Amount of physical memory to allocate
+** @param data Pointer to data to copy, or NULL
+** @param bytes Number of bytes to copy
+**
+** @return status of the allocation attempt
+*/
+int vm_add(pde_t *pdir, bool_t wr, bool_t sys, void *va, uint32_t size,
+ char *data, uint32_t bytes);
+
+/**
+** Name: vm_free
+**
+** Deallocate a page table hierarchy and all physical memory frames
+** in the user portion.
+**
+** @param pdir Pointer to the page directory
+*/
+void vm_free(pde_t *pdir);
+
+/*
+** Name: vm_map
+**
+** Create PTEs for virtual addresses starting at 'va' that refer to
+** physical addresses in the range [pa, pa+size-1]. We aren't guaranteed
+** that va is page-aligned.
+**
+** @param pdir Page directory for this address space
+** @param va The starting virtual address
+** @param pa The starting physical address
+** @param size Length of the range to be mapped
+** @param perm Permission bits for the PTEs
+*/
+int vm_map(pde_t *pdir, void *va, uint32_t pa, uint32_t size, int perm);
+
+/**
+** Name: vm_uvmdup
+**
+** Create a duplicate of the user portio of an existing page table
+** hierarchy. We assume that the "new" page directory exists and
+** the system portions of it should not be touched.
+**
+** @param new New page directory
+** @param old Existing page directory
+**
+** @return status of the duplication attempt
+*/
+int vm_uvmdup(pde_t *new, pde_t *old);
+
+/**
+** Name: vm_print
+**
+** Print out a paging hierarchy.
+**
+** @param pt Page table to display
+** @param dir Is it a page directory (vs. a page table)?
+** @param mode How to display the entries
+*/
+void vm_print(void *pt, bool_t dir, enum vmmode_e mode);
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/vmtables.h b/kernel/old/include/vmtables.h
new file mode 100644
index 0000000..83c0881
--- /dev/null
+++ b/kernel/old/include/vmtables.h
@@ -0,0 +1,43 @@
+/**
+** @file vmtables.h
+**
+** @author CSCI-452 class of 20245
+**
+** @brief Predefined VM tables
+*/
+
+#ifndef VMTABLES_H_
+#define VMTABLES_H_
+
+#include <defs.h>
+#include <types.h>
+#include <vm.h>
+
+#ifndef ASM_SRC
+
+/*
+** Initial page directory, for when the kernel is starting up
+**
+** we use large (4MB) pages here to allow us to use a one-level
+** paging hierarchy; the kernel will create a new page table
+** hierarchy once memory is initialized
+*/
+extern pde_t firstpdir[];
+
+/*
+** "Identity" page map table.
+**
+** This just maps the first 4MB of physical memory. It is initialized
+** in vm_init().
+*/
+extern pte_t id_map[];
+
+/*
+** Kernel address mappings, present in every page table
+*/
+extern mapping_t kmap[];
+extern const uint32_t n_kmap;
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/x86/arch.h b/kernel/old/include/x86/arch.h
new file mode 100644
index 0000000..df0b2e2
--- /dev/null
+++ b/kernel/old/include/x86/arch.h
@@ -0,0 +1,299 @@
+/*
+** @file arch.h
+**
+** @author Warren R. Carithers
+** @author K. Reek
+**
+** Definitions of constants and macros for use
+** with the x86 architecture and registers.
+**
+*/
+
+#ifndef X86ARCH_H_
+#define X86ARCH_H_
+
+/*
+** Video stuff
+*/
+#define VID_BASE_ADDR 0xB8000
+
+/*
+** Memory management
+*/
+#define SEG_PRESENT 0x80
+#define SEG_PL_0 0x00
+#define SEG_PL_1 0x20
+#define SEG_PL_2 0x40
+#define SEG_PL_3 0x50
+#define SEG_SYSTEM 0x00
+#define SEG_NON_SYSTEM 0x10
+#define SEG_32BIT 0x04
+#define DESC_IGATE 0x06
+
+/*
+** Exceptions
+*/
+#define N_EXCEPTIONS 256
+
+/*
+** Bit definitions in registers
+**
+** See IA-32 Intel Architecture SW Dev. Manual, Volume 3: System
+** Programming Guide, page 2-8.
+*/
+/*
+** EFLAGS
+*/
+#define EFL_RSVD 0xffc00000 /* reserved */
+#define EFL_MB0 0x00008020 /* must be zero */
+#define EFL_MB1 0x00000002 /* must be 1 */
+
+#define EFL_ID 0x00200000
+#define EFL_VIP 0x00100000
+#define EFL_VIF 0x00080000
+#define EFL_AC 0x00040000
+#define EFL_VM 0x00020000
+#define EFL_RF 0x00010000
+#define EFL_NT 0x00004000
+#define EFL_IOPL 0x00003000
+#define EFL_OF 0x00000800
+#define EFL_DF 0x00000400
+#define EFL_IF 0x00000200
+#define EFL_TF 0x00000100
+#define EFL_SF 0x00000080
+#define EFL_ZF 0x00000040
+#define EFL_AF 0x00000010
+#define EFL_PF 0x00000004
+#define EFL_CF 0x00000001
+
+/*
+** CR0, CR1, CR2, CR3, CR4
+**
+** IA-32 V3, page 2-12.
+*/
+#define CR0_RSVD 0x1ffaffc0
+#define CR0_PG 0x80000000
+#define CR0_CD 0x40000000
+#define CR0_NW 0x20000000
+#define CR0_AM 0x00040000
+#define CR0_WP 0x00010000
+#define CR0_NE 0x00000020
+#define CR0_ET 0x00000010
+#define CR0_TS 0x00000008
+#define CR0_EM 0x00000004
+#define CR0_MP 0x00000002
+#define CR0_PE 0x00000001
+
+#define CR1_RSVD 0xffffffff
+
+#define CR2_RSVD 0x00000000
+#define CR2_PF_LIN_ADDR 0xffffffff
+
+#define CR3_RSVD 0x00000fe7
+#define CR3_PD_BASE 0xfffff000
+#define CR3_PCD 0x00000010
+#define CR3_PWT 0x00000008
+
+#define CR4_RSVD 0xfd001000
+#define CR4_UINT 0x02000000
+#define CR4_PKS 0x01000000
+#define CR4_CET 0x00800000
+#define CR4_PKE 0x00400000
+#define CR4_SMAP 0x00200000
+#define CR4_SMEP 0x00100000
+#define CR4_KL 0x00080000
+#define CR4_OSXS 0x00040000
+#define CR4_PCID 0x00020000
+#define CR4_FSGS 0x00010000
+#define CR4_SMXE 0x00004000
+#define CR4_VMXE 0x00002000
+#define CR4_LA57 0x00001000
+#define CR4_UMIP 0x00000800
+#define CR4_OSXMMEXCPT 0x00000400
+#define CR4_OSFXSR 0x00000200
+#define CR4_PCE 0x00000100
+#define CR4_PGE 0x00000080
+#define CR4_MCE 0x00000040
+#define CR4_PAE 0x00000020
+#define CR4_PSE 0x00000010
+#define CR4_DE 0x00000008
+#define CR4_TSD 0x00000004
+#define CR4_PVI 0x00000002
+#define CR4_VME 0x00000001
+
+/*
+** PMode segment selector field masks
+**
+** IA-32 V3, page 3-8.
+*/
+#define SEG_SEL_IX_MASK 0xfff8
+#define SEG_SEL_TI_MASK 0x0004
+#define SEG_SEL_RPL_MASK 0x0003
+
+/*
+** Segment descriptor bytes
+**
+** IA-32 V3, page 3-10.
+**
+** Bytes:
+** 0, 1: segment limit 15:0
+** 2, 3: base address 15:0
+** 4: base address 23:16
+** 7: base address 31:24
+*/
+/*
+** Byte 5: access control bits
+** 7: present
+** 6-5: DPL
+** 4: system/user
+** 3-0: type
+*/
+#define SEG_ACCESS_P_MASK 0x80
+#define SEG_PRESENT 0x80
+#define SEG_NOT_PRESENT 0x00
+
+#define SEG_ACCESS_DPL_MASK 0x60
+#define SEG_DPL_0 0x00
+#define SEG_DPL_1 0x20
+#define SEG_DPL_2 0x40
+#define SEG_DPL_3 0x60
+
+#define SEG_ACCESS_S_MASK 0x10
+#define SEG_SYSTEM 0x00
+#define SEG_NON_SYSTEM 0x10
+
+#define SEG_TYPE_MASK 0x0f
+#define SEG_DATA_A_BIT 0x1
+#define SEG_DATA_W_BIT 0x2
+#define SEG_DATA_E_BIT 0x4
+#define SEG_CODE_A_BIT 0x1
+#define SEG_CODE_R_BIT 0x2
+#define SEG_CODE_C_BIT 0x4
+#define SEG_DATA_RO 0x0
+#define SEG_DATA_ROA 0x1
+#define SEG_DATA_RW 0x2
+#define SEG_DATA_RWA 0x3
+#define SEG_DATA_RO_XD 0x4
+#define SEG_DATA_RO_XDA 0x5
+#define SEG_DATA_RW_XW 0x6
+#define SEG_DATA_RW_XWA 0x7
+#define SEG_CODE_XO 0x8
+#define SEG_CODE_XOA 0x9
+#define SEG_CODE_XR 0xa
+#define SEG_CODE_XRA 0xb
+#define SEG_CODE_XO_C 0xc
+#define SEG_CODE_XO_CA 0xd
+#define SEG_CODE_XR_C 0xe
+#define SEG_CODE_XR_CA 0xf
+
+/*
+** Byte 6: sizes
+** 7: granularity
+** 6: d/b
+** 5: long mode
+** 4: available!
+** 3-0: upper 4 bits of limit
+** 7: base address 31:24
+*/
+#define SEG_SIZE_G_MASK 0x80
+#define SEG_GRAN_BYTE 0x00
+#define SEG_GRAN_4KBYTE 0x80
+
+#define SEG_SIZE_D_B_MASK 0x40
+#define SEG_DB_16BIT 0x00
+#define SEG_DB_32BIT 0x40
+
+#define SEG_SIZE_L_MASK 0x20
+#define SEG_L_64BIT 0x20
+#define SEG_L_32BIT 0x00
+
+#define SEG_SIZE_AVL_MASK 0x10
+
+#define SEG_SIZE_LIM_19_16_MASK 0x0f
+
+/*
+** System-segment and gate-descriptor types
+**
+** IA-32 V3, page 3-15.
+*/
+// type 0: reserved
+#define SEG_SYS_16BIT_TSS_AVAIL 0x1
+#define SEG_SYS_LDT 0x2
+#define SEG_SYS_16BIT_TSS_BUSY 0x3
+#define SEG_SYS_16BIT_CALL_GATE 0x4
+#define SEG_SYS_TASK_GATE 0x5
+#define SEG_SYS_16BIT_INT_GATE 0x6
+#define SEG_SYS_16BIT_TRAP_GATE 0x7
+// type 8: reserved
+#define SEG_SYS_32BIT_TSS_AVAIL 0x9
+// type A: reserved
+#define SEG_SYS_32BIT_TSS_BUSY 0xb
+#define SEG_SYS_32BIT_CALL_GATE 0xc
+// type D: reserved
+#define SEG_SYS_32BIT_INT_GATE 0xe
+#define SEG_SYS_32BIT_TRAP_GATE 0xf
+
+/*
+** IDT Descriptors
+**
+** IA-32 V3, page 5-13.
+**
+** All have a segment selector in bytes 2 and 3; Task Gate descriptors
+** have bytes 0, 1, 4, 6, and 7 reserved; others have bytes 0, 1, 6,
+** and 7 devoted to the 16 bits of the Offset, with the low nybble of
+** byte 4 reserved.
+*/
+#define IDT_PRESENT 0x8000
+#define IDT_DPL_MASK 0x6000
+#define IDT_DPL_0 0x0000
+#define IDT_DPL_1 0x2000
+#define IDT_DPL_2 0x4000
+#define IDT_DPL_3 0x6000
+#define IDT_GATE_TYPE 0x0f00
+#define IDT_TASK_GATE 0x0500
+#define IDT_INT16_GATE 0x0600
+#define IDT_INT32_GATE 0x0e00
+#define IDT_TRAP16_GATE 0x0700
+#define IDT_TRAP32_GATE 0x0f00
+
+/*
+** Interrupt vectors
+*/
+// predefined by the architecture
+#define VEC_DIVIDE_ERROR 0x00
+#define VEC_DEBUG_EXCEPTION 0x01
+#define VEC_NMI_INTERRUPT 0x02
+#define VEC_BREAKPOINT 0x03
+#define VEC_OVERFLOW 0x04
+#define VEC_BOUND_RANGE_EXCEEDED 0x05
+#define VEC_INVALID_OPCODE 0x06
+#define VEC_DEVICE_NOT_AVAILABLE 0x07
+#define VEC_DOUBLE_FAULT 0x08
+#define VEC_COPROCESSOR_OVERRUN 0x09
+#define VEC_INVALID_TSS 0x0a
+#define VEC_SEGMENT_NOT_PRESENT 0x0b
+#define VEC_STACK_FAULT 0x0c
+#define VEC_GENERAL_PROTECTION 0x0d
+#define VEC_PAGE_FAULT 0x0e
+// 0x0f is reserved - unused
+#define VEC_FPU_ERROR 0x10
+#define VEC_ALIGNMENT_CHECK 0x11
+#define VEC_MACHINE_CHECK 0x12
+#define VEC_SIMD_FP_EXCEPTION 0x13
+#define VEC_VIRT_EXCEPTION 0x14
+#define VEC_CTRL_PROT_EXCEPTION 0x15
+// 0x16 through 0x1f are reserved
+
+// 0x20 through 0xff are user-defined, non-reserved
+
+// IRQ0 through IRQ15 will use vectors 0x20 through 0x2f
+#define VEC_TIMER 0x20
+#define VEC_KBD 0x21
+#define VEC_COM2 0x23
+#define VEC_COM1 0x24
+#define VEC_PARALLEL 0x25
+#define VEC_FLOPPY 0x26
+#define VEC_MYSTERY 0x27
+#define VEC_MOUSE 0x2c
+
+#endif
diff --git a/kernel/old/include/x86/ops.h b/kernel/old/include/x86/ops.h
new file mode 100644
index 0000000..81167a1
--- /dev/null
+++ b/kernel/old/include/x86/ops.h
@@ -0,0 +1,395 @@
+/**
+** @file ops.h
+**
+** @author Warren R. Carithers
+**
+** @brief Inline escapes to assembly for efficiency
+**
+** Inspiration from:
+** Martins Mozeiko, https://gist.github.com/mmozeiko/f68ad2546bd6ab953315
+** MIT's xv6, https://github.com/mit-pdos/xv6-public
+**
+** Note: normally, GCC doesn't inline unless the optimization level is
+** over 1. This can be forced by adding
+**
+** __attribute__((always_inline))
+**
+** after the parameter list on each declaration. This is enabled by
+** defining the compile-time CPP symbol FORCE_INLINING.
+*/
+
+#ifndef OPS_H_
+#define OPS_H_
+
+#include <common.h>
+
+#ifndef ASM_SRC
+
+// control "forced" inlining
+#ifdef FORCE_INLINING
+#define OPSINLINED __attribute__((always_inline))
+#else
+#define OPSINLINED /* no-op */
+#endif /* FORCE_INLINING */
+
+/****************************
+** Data movement
+****************************/
+
+/**
+** Block move functions
+**
+** Variations: movsb(), movsl(), movsq()
+**
+** Description: Copy from source buffer to destination buffer
+**
+** @param dst Destination buffer
+** @param src Source buffer
+** @param len Byte count
+*/
+static inline void movsb(void *dst, const void *src, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep movsb"
+ : "+D"(dst), "+S"(src), "+c"(len)
+ :
+ : "memory");
+}
+static inline void movsw(void *dst, const void *src, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep movsw"
+ : "+D"(dst), "+S"(src), "+c"(len)
+ :
+ : "memory");
+}
+static inline void movsl(void *dst, const void *src, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep movsl"
+ : "+D"(dst), "+S"(src), "+c"(len)
+ :
+ : "memory");
+}
+static inline void movsq(void *dst, const void *src, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep movsq"
+ : "+D"(dst), "+S"(src), "+c"(len)
+ :
+ : "memory");
+}
+
+/**
+** Block store functions
+**
+** Variations: stosb(), stosw(), stosl()
+**
+** Description: Store a specific value into destination buffer
+**
+** @param dst Destination buffer
+** @param val Data to copy
+** @param len Byte count
+*/
+static inline void stosb(void *dst, uint8_t val, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep stosb"
+ : "=D"(dst), "=c"(len)
+ : "0"(dst), "1"(len), "a"(val)
+ : "memory", "cc");
+}
+static inline void stosw(void *dst, uint16_t val, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep stos2"
+ : "=D"(dst), "=c"(len)
+ : "0"(dst), "1"(len), "a"(val)
+ : "memory", "cc");
+}
+static inline void stosl(void *dst, uint32_t val, uint32_t len) OPSINLINED
+{
+ __asm__ __volatile__("cld; rep stosl"
+ : "=D"(dst), "=c"(len)
+ : "0"(dst), "1"(len), "a"(val)
+ : "memory", "cc");
+}
+
+/****************************
+** Special register access
+****************************/
+
+/**
+** Register read functions
+**
+** Variations: r_cr0(), r_cr2(), r_cr3(), r_cr4(), r_eflags(),
+** r_ebp(), r_esp()
+**
+** Description: Reads the register indicated by its name
+**
+** @return Contents of the register
+*/
+static inline uint32_t r_cr0(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%cr0,%0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_cr2(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%cr2,%0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_cr3(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%cr3,%0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_cr4(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%cr4,%0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_eflags(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("pushfl; popl %0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_ebp(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%ebp,%0" : "=r"(val));
+ return val;
+}
+static inline uint32_t r_esp(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl %%esp,%0" : "=r"(val));
+ return val;
+}
+
+/**
+** Register write functions
+**
+** Variations: w_cr0(), w_cr2(), w_cr3(), w_cr4(), w_eflags()
+**
+** Description: Writes a value into the CR indicated by its name
+*/
+static inline void w_cr0(uint32_t val) OPSINLINED
+{
+ __asm__ __volatile__("movl %0,%%cr0" : : "r"(val));
+}
+static inline void w_cr2(uint32_t val) OPSINLINED
+{
+ __asm__ __volatile__("movl %0,%%cr2" : : "r"(val));
+}
+static inline void w_cr3(uint32_t val) OPSINLINED
+{
+ __asm__ __volatile__("movl %0,%%cr3" : : "r"(val));
+}
+static inline void w_cr4(uint32_t val) OPSINLINED
+{
+ __asm__ __volatile__("movl %0,%%cr4" : : "r"(val));
+}
+static inline void w_eflags(uint32_t eflags) OPSINLINED
+{
+ __asm__ __volatile__("pushl %0; popfl" : : "r"(eflags));
+}
+
+/**
+** Descriptor table load functions
+**
+** Variations: w_gdt(), w_idt()
+**
+** Description: Load an address into the specified processor register
+**
+** @param addr The value to be loaded into the register
+*/
+static inline void w_gdt(void *addr) OPSINLINED
+{
+ __asm__ __volatile__("lgdt (%0)" : : "r"(addr));
+}
+static inline void w_idt(void *addr) OPSINLINED
+{
+ __asm__ __volatile__("lidt (%0)" : : "r"(addr));
+}
+
+/**
+** CPU ID access
+**
+** Description: Retrieve CPUID information
+**
+** @param op Value to be placed into %eax for the operation
+** @param ap Pointer to where %eax contents should be saved, or NULL
+** @param bp Pointer to where %ebx contents should be saved, or NULL
+** @param cp Pointer to where %ecx contents should be saved, or NULL
+** @param dp Pointer to where %edx contents should be saved, or NULL
+*/
+static inline void cpuid(uint32_t op, uint32_t *ap, uint32_t *bp, uint32_t *cp,
+ uint32_t *dp) OPSINLINED
+{
+ uint32_t eax, ebx, ecx, edx;
+ __asm__ __volatile__("cpuid"
+ : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ : "a"(op));
+ if (ap)
+ *ap = eax;
+ if (bp)
+ *bp = ebx;
+ if (cp)
+ *cp = ecx;
+ if (dp)
+ *dp = edx;
+}
+
+/****************************
+** TLB management
+****************************/
+
+/**
+** TLB invalidation for one page
+**
+** Description: Invalidate the TLB entry for an address
+**
+** @param addr An address within the page to be flushed
+*/
+static inline void invlpg(uint32_t addr) OPSINLINED
+{
+ __asm__ __volatile__("invlpg (%0)" : : "r"(addr) : "memory");
+}
+
+/**
+** TLB invalidation for all pages
+**
+** Description: Flush all entries from the TLB
+**
+** We do this by changing CR3.
+*/
+static inline void flushtlb(void) OPSINLINED
+{
+ uint32_t cr3;
+ __asm__ __volatile__("movl %%cr3,%0" : "=r"(cr3));
+ __asm__ __volatile__("movl %0,%%cr2" : : "r"(cr3));
+}
+
+/****************************
+** I/O instructions
+****************************/
+
+/**
+** Name: inN
+**
+** Variations: inb(), inw(), inl()
+**
+** Description: Read some amount of data from the supplied I/O port
+**
+** @param port The i/o port to read from
+**
+** @return The data read from the specified port
+*/
+static inline uint8_t inb(int port) OPSINLINED
+{
+ uint8_t data;
+ __asm__ __volatile__("inb %w1,%0" : "=a"(data) : "d"(port));
+ return data;
+}
+static inline uint16_t inw(int port) OPSINLINED
+{
+ uint16_t data;
+ __asm__ __volatile__("inw %w1,%0" : "=a"(data) : "d"(port));
+ return data;
+}
+static inline uint32_t inl(int port) OPSINLINED
+{
+ uint32_t data;
+ __asm__ __volatile__("inl %w1,%0" : "=a"(data) : "d"(port));
+ return data;
+}
+
+/**
+** Name: outN
+**
+** Variations: outb(), outw(), outl()
+**
+** Description: Write some data to the specified I/O port
+**
+** @param port The i/o port to write to
+** @param data The data to be written to the port
+**
+** @return The data read from the specified port
+*/
+static inline void outb(int port, uint8_t data) OPSINLINED
+{
+ __asm__ __volatile__("outb %0,%w1" : : "a"(data), "d"(port));
+}
+static inline void outw(int port, uint16_t data) OPSINLINED
+{
+ __asm__ __volatile__("outw %0,%w1" : : "a"(data), "d"(port));
+}
+static inline void outl(int port, uint32_t data) OPSINLINED
+{
+ __asm__ __volatile__("outl %0,%w1" : : "a"(data), "d"(port));
+}
+
+/****************************
+** Miscellaneous instructions
+****************************/
+
+/**
+** Name: breakpoint
+**
+** Description: Cause a breakpoint interrupt for debugging purposes
+*/
+static inline void breakpoint(void) OPSINLINED
+{
+ __asm__ __volatile__("int3");
+}
+
+/**
+** Name: get_ra
+**
+** Description: Get the return address for the calling function
+** (i.e., where whoever called us will go back to)
+**
+** @return The address the calling routine will return to as a uint32_t
+*/
+static inline uint32_t get_ra(void) OPSINLINED
+{
+ uint32_t val;
+ __asm__ __volatile__("movl 4(%%ebp),%0" : "=r"(val));
+ return val;
+}
+
+/**
+** Name: ev_wait
+**
+** Description: Pause until something happens
+*/
+static inline void ev_wait(void) OPSINLINED
+{
+ __asm__ __volatile__("sti ; hlt");
+}
+
+/**
+** Name: xchgl
+**
+** Description: Perform an atomic exchange with memory
+**
+** @param addr Memory location to be modified
+** @param data Data to exchange
+**
+** @return The old contents of the memory location
+*/
+static inline uint32_t xchgl(volatile uint32_t *addr, uint32_t data) OPSINLINED
+{
+ uint32_t old;
+
+ // + indicates a read-modify-write operand
+ __asm__ __volatile__("lock; xchgl %0, %1"
+ : "+m"(*addr), "=a"(old)
+ : "1"(data)
+ : "cc");
+ return old;
+}
+
+#endif /* !ASM_SRC */
+
+#endif
diff --git a/kernel/old/include/x86/pic.h b/kernel/old/include/x86/pic.h
new file mode 100644
index 0000000..ae3fe6c
--- /dev/null
+++ b/kernel/old/include/x86/pic.h
@@ -0,0 +1,136 @@
+/**
+** @file pic.h
+**
+** @author Warren R. Carithers
+** @author K. Reek
+**
+** Definitions of constants and macros for the Intel 8259 Programmable
+** Interrupt Controller.
+**
+*/
+
+#ifndef X86PIC_H_
+#define X86PIC_H_
+
+/*
+** Our expected configuration is two PICs, with the secondary connected
+** through the IRQ2 pin of the primary.
+*/
+/*
+** Port addresses for the command port and interrupt mask register port
+** for both the primary and secondary PICs.
+*/
+#define PIC1_CMD 0x20 // primary command
+#define PIC1_DATA (PIC1_CMD + 1) // primary data / int mask register
+#define PIC2_CMD 0xA0 // secondary command
+#define PIC2_DATA (PIC2_CMD + 1) // secondary data / int mask register
+
+/*
+** Initialization Command Word (ICW) definitions
+**
+** Initialization sequence:
+** ICW1 Init command is sent to each command port.
+** ICW2 vector commands are sent to the data ports.
+** If "cascade mode" was selected, send ICW3 commands to the data ports.
+** If "need ICW4" was selected, send ICW4 commands to the data ports.
+**
+** Following that sequence, the PIC is ready to accept interrupts;
+** it will also accept Output Command Words (OCWs) to the data ports.
+**
+** PIC1_* defines are intended for the primary PIC
+** PIC2_* defines are intended for the secondary PIC
+** PIC_* defines are sent to both PICs
+*/
+/*
+** ICW1: initialization, send to command port
+*/
+#define PIC_CW1_INIT 0x10 // start initialization sequence
+#define PIC_CW1_NEED4 0x01 // ICW4 will also be set
+#define PIC_CW1_SINGLE 0x02 // select single (vs. cascade) mode
+#define PIC_CW1_INTVAL 0x04 // set call interval to 4 (vs. 8)
+#define PIC_CW1_LEVEL 0x08 // use level-triggered mode (vs. edge)
+
+/*
+** ICW2: interrupt vector base offsets, send to data port
+*/
+#define PIC1_CW2_VECBASE 0x20 // IRQ0 int vector number
+#define PIC2_CW2_VECBASE 0x28 // IRQ8 int vector number
+
+/*
+** ICW3: secondary::primary attachment, send to data port
+*/
+#define PIC1_CW3_SEC_IRQ2 0x04 // bit mask: secondary is on pin 2
+#define PIC2_CW3_SEC_ID 0x02 // integer: secondary id
+
+/*
+** ICW4: operating mode, send to data port
+*/
+#define PIC_CW4_PM86 0x01 // 8086 mode (vs. 8080/8085)
+#define PIC_CW4_AUTOEOI 0x02 // do auto eoi's
+#define PIC_CW4_UNBUF 0x00 // unbuffered mode
+#define PIC_CW4_SEC_BUF 0x08 // put secondary in buffered mode
+#define PIC_CW4_PRI_BUF 0x0C // put primary in buffered mode
+#define PIC_CW4_SFNMODE 0x10 // "special fully nested" mode
+
+/*
+** Operation Control Words (OCWs)
+**
+** After the init sequence, can send these
+*/
+/*
+** OCW1: interrupt mask; send to data port
+*/
+#define PIC_MASK_NONE 0x00 // allow all interrupts
+#define PIC_MASK_NO_IRQ0 0x01 // prevent IRQ0 interrupts
+#define PIC_MASK_NO_IRQ1 0x02 // prevent IRQ1 interrupts
+#define PIC_MASK_NO_IRQ2 0x04 // prevent IRQ2 interrupts
+#define PIC_MASK_NO_IRQ3 0x08 // prevent IRQ3 interrupts
+#define PIC_MASK_NO_IRQ4 0x10 // prevent IRQ4 interrupts
+#define PIC_MASK_NO_IRQ5 0x20 // prevent IRQ5 interrupts
+#define PIC_MASK_NO_IRQ6 0x40 // prevent IRQ6 interrupts
+#define PIC_MASK_NO_IRQ7 0x80 // prevent IRQ7 interrupts
+#define PIC_MASK_ALL 0xff // prevent all interrupts
+
+/*
+** OCW2: EOI control, interrupt level; send to command port
+*/
+#define PIC_LVL_0 0x00 // act on IRQ level 0
+#define PIC_LVL_1 0x01 // act on IRQ level 1
+#define PIC_LVL_2 0x02 // act on IRQ level 2
+#define PIC_LVL_3 0x03 // act on IRQ level 3
+#define PIC_LVL_4 0x04 // act on IRQ level 4
+#define PIC_LVL_5 0x05 // act on IRQ level 5
+#define PIC_LVL_6 0x06 // act on IRQ level 6
+#define PIC_LVL_7 0x07 // act on IRQ level 7
+
+#define PIC_EOI_NON_SPEC 0x20 // non-specific EOI command
+#define PIC_EOI PIC_EOI_NON_SPEC
+
+#define PIC_EOI_SPEC 0x60 // specific EOI command
+#define PIC_SEOI PIC_EOI_SPEC
+#define PIC_SEOI_LVL0 (PIC_EOI_SPEC | PIC_LVL_0)
+#define PIC_SEOI_LVL1 (PIC_EOI_SPEC | PIC_LVL_1)
+#define PIC_SEOI_LVL2 (PIC_EOI_SPEC | PIC_LVL_2)
+#define PIC_SEOI_LVL3 (PIC_EOI_SPEC | PIC_LVL_3)
+#define PIC_SEOI_LVL4 (PIC_EOI_SPEC | PIC_LVL_4)
+#define PIC_SEOI_LVL5 (PIC_EOI_SPEC | PIC_LVL_5)
+#define PIC_SEOI_LVL6 (PIC_EOI_SPEC | PIC_LVL_6)
+#define PIC_SEOI_LVL7 (PIC_EOI_SPEC | PIC_LVL_7)
+
+#define PIC_EOI_ROT_NONSP 0xa0 // rotate on non-spec EOI cmd
+#define PIC_EOI_SET_ROT_AUTO 0x80 // set "rotate in auto EOI mode"
+#define PIC_EOI_CLR_ROT_AUTO 0x00 // clear "rotate in auto EOI mode"
+#define PIC_EOI_ROT_SPEC 0xe0 // rotate on spec EOI cmd (+ level)
+#define PIC_EOI_SET_PRIO 0xc0 // set priority (+ level)
+#define PIC_EOI_NOP 0x40 // no operation
+
+/*
+** OCW3: read requests, special mask mode; send to command port
+*/
+#define PIC_READIRR 0x0a // read the IR register
+#define PIC_READISR 0x0b // read the IS register
+#define PIC_POLL 0x0c // poll
+#define PIC_MASK_RESET 0x48 // reset special mask mode
+#define PIC_MASK_SET 0x68 // set special mask mode
+
+#endif
diff --git a/kernel/old/include/x86/pit.h b/kernel/old/include/x86/pit.h
new file mode 100644
index 0000000..0c54539
--- /dev/null
+++ b/kernel/old/include/x86/pit.h
@@ -0,0 +1,81 @@
+/*
+** @file pit.h
+**
+** @author Warren R. Carithers
+** @author K. Reek
+**
+** Definitions of constants and macros for the
+** Intel 8254 Programmable Interval Timer
+**
+*/
+
+#ifndef X86PIT_H_
+#define X86PIT_H_
+
+/*
+** Hardware timer (Intel 8254 Programmable Interval Timer)
+**
+** Control word layout:
+**
+** Bit 7 6 | 5 4 | 3 2 1 | 0
+** Field SC1 SC0|RW1 RW0|M2 M1 M0 |BCD
+**
+** SC - select counter
+** RW - read/write
+** M - mode
+** BCD - binary or BCD counter
+*/
+/* Frequency settings */
+#define PIT_DEFAULT_TICKS_PER_SECOND 18 // actually 18.2065Hz
+#define PIT_DEFAULT_MS_PER_TICK (1000 / PIT_DEFAULT_TICKS_PER_SECOND)
+#define PIT_FREQ 1193182 // clock cycles/sec
+
+/* Port assignments */
+#define PIT_BASE_PORT 0x40 // I/O port for the timer
+#define PIT_0_PORT (PIT_BASE_PORT)
+#define PIT_1_PORT (PIT_BASE_PORT + 1)
+#define PIT_2_PORT (PIT_BASE_PORT + 2)
+#define PIT_CONTROL_PORT (PIT_BASE_PORT + 3)
+
+/* BCD field */
+#define PIT_USE_DECIMAL 0x00 // 16-bit binary counter (default)
+#define PIT_USE_BCD 0x01 // BCD counter
+
+/* Timer modes */
+#define PIT_MODE_0 0x00 // int on terminal count
+#define PIT_MODE_1 0x02 // one-shot
+#define PIT_MODE_2 0x04 // divide-by-N
+#define PIT_MODE_3 0x06 // square-wave
+#define PIT_MODE_4 0x08 // software strobe
+#define PIT_MODE_5 0x0a // hardware strobe
+
+/* Timer 0 settings */
+#define PIT_0_SELECT 0x00 // select timer 0
+#define PIT_0_LOAD 0x30 // load LSB, then MSB
+#define PIT_0_NDIV PIT_MODE_2 // divide-by-N counter
+#define PIT_0_SQUARE PIT_MODE_3 // square-wave mode
+#define PIT_0_ENDSIGNAL 0x00 // assert OUT at end of count
+
+/* Timer 1 settings */
+#define PIT_1_SELECT 0x40 // select timer 1
+#define PIT_1_READ 0x30 // read/load LSB then MSB
+#define PIT_1_RATE 0x06 // square-wave, for USART
+
+/* Timer 2 settings */
+#define PIT_2_SELECT 0x80 // select timer 1
+#define PIT_2_READ 0x30 // read/load LSB then MSB
+#define PIT_2_RATE 0x06 // square-wave, for USART
+
+/* Timer read-back */
+
+#define PIT_READBACK 0xc0 // perform a read-back
+#define PIT_RB_NOT_COUNT 0x20 // don't latch the count
+#define PIT_RB_NOT_STATUS 0x10 // don't latch the status
+#define PIT_RB_CHAN_2 0x08 // read back channel 2
+#define PIT_RB_CHAN_1 0x04 // read back channel 1
+#define PIT_RB_CHAN_0 0x02 // read back channel 0
+#define PIT_RB_ACCESS_MASK 0x30 // access mode field
+#define PIT_RB_OP_MASK 0x0e // oper mode field
+#define PIT_RB_BCD_MASK 0x01 // BCD mode field
+
+#endif
diff --git a/kernel/old/include/x86/uart.h b/kernel/old/include/x86/uart.h
new file mode 100644
index 0000000..293b7b7
--- /dev/null
+++ b/kernel/old/include/x86/uart.h
@@ -0,0 +1,348 @@
+/*
+** @file uart.h
+**
+** @author M. Reek
+** @authors K. Reek, Warren R. Carithers
+**
+** Definitions for a 16540/16550 compatible UART. Definitions are taken
+** from datasheets for the National Semiconductor INS8250, NS16450, and
+** NS16550 UART chips, and the PC87309 Super I/O legacy peripheral chip.
+**
+** The naming convention is UAx_yyy_zzzzz. "x" is either 4 or 5 (see below),
+** "yyy" is the name of the register to which this value applies, and
+** "zzzzz" is the name of the value or field.
+**
+** The UA4 prefix denotes 16540 compatible functions, available in both
+** chips. The UA5 prefix denotes 16550-only functions (primarily the FIFOs).
+**
+** For many items there are two names: one short one that matches the name
+** in the chip manual, and another that is more readable.
+*/
+
+#ifndef UART_H
+#define UART_H
+
+/*********************************************************************
+***************************** I/O PORTS ******************************
+*********************************************************************/
+
+/*
+** Base port number assigned to the device
+*/
+#define UA4_COM1_PORT 0x3f8
+#define UA4_COM2_PORT 0x2f8
+#define UA4_COM3_PORT 0x3e8
+#define UA4_COM4_PORT 0x2e8
+
+// short name for the one we'll use
+#define UA4_PORT UA4_COM1_PORT
+#define UA5_PORT UA4_COM1_PORT
+
+/*
+** Registers
+**
+** The 164x0 chips have the following registers. The (RO) and (WO)
+** suffixes indicate read-only and write-only access.
+**
+** Index Register(s)
+** ===== =========================================
+** 0 Receiver Data (RO), Transmitter Data (WO)
+** 1 Interrupt Enable
+** 2 Interrupt ID (RO), FIFO Control (WO)
+** 3 Line Control, Divisor Latch
+** 4 Modem Control
+** 5 Line Status
+** 6 Modem Status
+** 7 Scratch
+**
+** Registers indices are relative to the base I/O port for the
+** specific UART port being used (e.g., for COM1, the port addresses
+** are 0x3f8 through 0x3ff). When two registers share a port and have
+** different access methods (RO vs. WO), a read from the port accesses
+** the RO register and a write to the port access the WO register.
+**
+** The Line Control and Divisor Latch registers are accessed by writing
+** a byte to the port; the high-order bit determines which register is
+** accessed (0 selects Line Control, 1 selects Divisor Latch), with the
+** remaining bits selecting fields within the indicated register.
+*/
+/*
+** Receiver Data Register (read-only)
+*/
+#define UA4_RXD (UA4_PORT + 0)
+#define UA4_RX_DATA UA4_RXD
+
+/*
+** Transmitter Data Register (write-only)
+*/
+#define UA4_TXD (UA4_PORT + 0)
+#define UA4_TX_DATA UA4_TXD
+
+/*
+** Interrupt Enable Register
+*/
+#define UA4_IER (UA4_PORT + 1)
+#define UA4_INT_ENABLE_REG UA4_IER
+
+// fields
+#define UA4_IER_RX_IE 0x01 // Rcvr High-Data-Level Int Enable
+#define UA4_IER_TX_IE 0x02 // Xmitter Low-data-level Int Enable
+#define UA4_IER_LS_IE 0x04 // Line Status Int Enable
+#define UA4_IER_MS_IE 0x08 // Modem Status Int Enable
+
+// aliases
+#define UA4_IER_RX_INT_ENABLE UA4_IER_RX_IE
+#define UA4_IER_TX_INT_ENABLE UA4_IER_TX_IE
+#define UA4_IER_LINE_STATUS_INT_ENABLE UA4_IER_LS_IE
+#define UA4_IER_MODEM_STATUS_INT_ENABLE UA4_IER_MS_IE
+
+/*
+** Interrupt Identification Register (read-only)
+**
+** a.k.a. Event Identification Register
+*/
+#define UA4_IIR (UA4_PORT + 2)
+#define UA4_EVENT_ID UA4_IIR
+
+// fields
+#define UA4_IIR_IPF 0x01 // Interrupt Pending flag
+
+#define UA4_IIR_IPR_MASK 0x06 // Interrupt Priority mask
+#define UA4_IIR_IPR0_MASK 0x02 // IPR bit 0 mask
+#define UA4_IIR_IPR1_MASK 0x04 // IPR bit 1 mask
+
+#define UA5_IIR_RXFT 0x08 // RX_FIFO Timeout
+#define UA5_IIR_FEN0 0x40 // FIFOs Enabled
+#define UA5_IIR_FEN1 0x80 // FIFOs Enabled
+
+// aliases
+#define UA4_IIR_INT_PENDING UA4_IIR_IPF
+#define UA4_IIR_INT_PRIORITY UA4_IIR_IPR
+#define UA5_IIR_RX_FIFO_TIMEOUT UA5_IIR_RXFT
+#define UA5_IIR_FIFO_ENABLED_0 UA5_IIR_FEN0
+#define UA5_IIR_FIFO_ENABLED_1 UA5_IIR_FEN1
+
+// IIR interrupt priorities (four-bit values)
+#define UA4_IIR_INT_PRI_MASK 0x0f // Mask for extracting int priority
+#define UA4_IIR_NO_INT 0x01 // no interrupt
+#define UA4_IIR_LINE_STATUS 0x06 // line status interrupt
+#define UA4_IIR_RX 0x04 // Receiver High Data Level
+#define UA5_IIR_RX_FIFO 0x0c // Receiver FIFO timeout (16550)
+#define UA4_IIR_TX 0x02 // Transmitter Low Data level
+#define UA4_IIR_MODEM_STATUS 0x00 // Modem Status
+
+// aliases
+#define UA4_IIR_NO_INT_PENDING UA4_IIR_NO_INT
+#define UA4_IIR_LINE_STATUS_INT_PENDING UA4_IIR_LINE_STATUS
+#define UA4_IIR_RX_INT_PENDING UA4_IIR_RX
+#define UA5_IIR_RX_FIFO_TIMEOUT_INT_PENDING UA5_IIR_RX_FIFO
+#define UA4_IIR_TX_INT_PENDING UA4_IIR_TX
+#define UA4_IIR_MODEM_STATUS_INT_PENDING UA4_IIR_MODEM_STATUS
+
+/*
+** FIFO Control Register (16550 only, write-only)
+*/
+#define UA5_FCR (UA5_PORT + 2)
+#define UA5_FIFO_CTL UA5_FCR
+
+#define UA5_FCR_FIFO_RESET 0x00 // Reset the FIFO
+#define UA5_FCR_FIFO_EN 0x01 // FIFO Enable
+#define UA5_FCR_RXSR 0x02 // Receiver Soft Reset
+#define UA5_FCR_TXSR 0x04 // Transmitter Soft Reset
+
+#define UA5_FCR_TXFT_MASK 0x30 // TX_FIFO threshold level mask
+#define UA5_FCR_TXFT0_MASK 0x10 // TXFT bit 0 mask
+#define UA5_FCR_TXFT1_MASK 0x20 // TXFT bit 1 mask
+#define UA5_FCR_TX_FIFO_1 0x00 // 1 char
+#define UA5_FCR_TX_FIFO_3 0x10 // 3 char
+#define UA5_FCR_TX_FIFO_9 0x20 // 9 char
+#define UA5_FCR_TX_FIFO_13 0x30 // 13 char
+
+#define UA5_FCR_RXFT_MASK 0xc0 // RX_FIFO threshold level mask
+#define UA5_FCR_RXFT0_MASK 0x40 // RXFT bit 0 mask
+#define UA5_FCR_RXFT1_MASK 0x80 // RXFT bit 1 mask
+#define UA5_FCR_RX_FIFO_1 0x00 // 1 char
+#define UA5_FCR_RX_FIFO_4 0x40 // 4 char
+#define UA5_FCR_RX_FIFO_8 0x80 // 8 char
+#define UA5_FCR_RX_FIFO_14 0xc0 // 14 char
+
+// aliases
+#define UA5_FCR_FIFO_ENABLED UA5_FCR_FIFO_EN
+#define UA5_FCR_RX_SOFT_RESET UA5_FCR_RXSR
+#define UA5_FCR_TX_SOFT_RESET UA5_FCR_TXSR
+#define UA5_FCR_TX_FIFO_1_CHAR UA5_FCR_TX_FIFO_1
+#define UA5_FCR_TX_FIFO_3_CHAR UA5_FCR_TX_FIFO_3
+#define UA5_FCR_TX_FIFO_9_CHAR UA5_FCR_TX_FIFO_9
+#define UA5_FCR_TX_FIFO_13_CHAR UA5_FCR_TX_FIFO_13
+#define UA5_FCR_RX_FIFO_1_CHAR UA5_FCR_RX_FIFO_1
+#define UA5_FCR_RX_FIFO_4_CHAR UA5_FCR_RX_FIFO_4
+#define UA5_FCR_RX_FIFO_8_CHAR UA5_FCR_RX_FIFO_8
+#define UA5_FCR_RX_FIFO_14_CHAR UA5_FCR_RX_FIFO_14
+
+/*
+** Line Control Register (available in all banks)
+**
+** Selected when bit 7 of the value written to the port is a 0.
+*/
+#define UA4_LCR (UA4_PORT + 3)
+#define UA4_LINE_CTL UA4_LCR
+
+#define UA4_LCR_WLS_MASK 0x03 // Word Length Select mask
+#define UA4_LCR_WLS0_MASK 0x01 // WLS bit 0 mask
+#define UA4_LCR_WLS1_MASK 0x02 // WLS bit 1 mask
+#define UA4_LCR_WLS_5 0x00 // 5 bits per char
+#define UA4_LCR_WLS_6 0x01 // 6 bits per char
+#define UA4_LCR_WLS_7 0x02 // 7 bits per char
+#define UA4_LCR_WLS_8 0x03 // 8 bits per char
+
+#define UA4_LCR_STB 0x04 // Stop Bits
+#define UA4_LCR_1_STOP_BIT 0x00
+#define UA4_LCR_2_STOP_BIT 0x04
+
+#define UA4_LCR_PEN 0x08 // Parity Enable
+#define UA4_LCR_EPS 0x10 // Even Parity Select
+#define UA4_LCR_STKP 0x20 // Sticky Parity
+#define UA4_LCR_NO_PARITY 0x00
+#define UA4_LCR_ODD_PARITY UA4_LCR_PEN
+#define UA4_LCR_EVEN_PARITY (UA4_LCR_PEN | UA4_LCR_EPS)
+#define UA4_LCR_PARITY_LOGIC_1 (UA4_LCR_PEN | UA4_LCR_STKP)
+#define UA4_LCR_PARITY_LOGIC_0 (UA4_LCR_PEN | UA4_LCR_EPS | UA4_LCR_STKP)
+
+#define UA4_LCR_SBRK 0x40 // Set Break
+#define UA4_LCR_DLAB 0x80 // Divisor Latch select bit
+
+// aliases
+#define UA4_LCR_STOP_BITS UA4_LCR_STB
+#define UA4_LCR_PARITY_ENABLE UA4_LCR_PEN
+#define UA4_LCR_SET_BREAK UA4_LCR_SBRK
+#define UA4_LCR_BANK_SELECT_ENABLE UA4_LCR_BKSE
+
+/*
+** Divisor Latch Registers
+** Divisor Latch Least Significant (DLL)
+** Divisor Latch Most Significant (DLM)
+**
+** These contain the lower and upper halves of the 16-bit divisor for
+** baud rate generation.
+**
+** Accessing them requires sending a command to LCR with the most
+** significant bit (0x80, the DLAB field) set. This "unlocks" the
+** Divisor Latch registers, which are accessed at UA4_PORT+0 and
+** UA4_PORT+1 (i.e., in place of the RXD/TXD and IE registers). To
+** "re-lock" the Divisor Latch registers, write a command byte to
+** LCR with 0 in the DLAB bit.
+*/
+#define UA4_DLL (UA4_PORT + 0) // Divisor Latch (least sig.)
+#define UA4_DLM (UA4_PORT + 1) // Divisor Latch (most sig.)
+
+// aliases
+#define UA4_DIVISOR_LATCH_LS UA4_DLL
+#define UA4_DIVISOR_LATCH_MS UA4_DLM
+
+// Baud rate divisor high and low bytes
+#define BAUD_HIGH_BYTE(x) (((x) >> 8) & 0xff)
+#define BAUD_LOW_BYTE(x) ((x) & 0xff)
+
+// Baud rate divisors
+#define DL_BAUD_50 2304
+#define DL_BAUD_75 1536
+#define DL_BAUD_110 1047
+#define DL_BAUD_150 768
+#define DL_BAUD_300 384
+#define DL_BAUD_600 192
+#define DL_BAUD_1200 96
+#define DL_BAUD_1800 64
+#define DL_BAUD_2000 58
+#define DL_BAUD_2400 48
+#define DL_BAUD_3600 32
+#define DL_BAUD_4800 24
+#define DL_BAUD_7200 16
+#define DL_BAUD_9600 12
+#define DL_BAUD_14400 8
+#define DL_BAUD_19200 6
+#define DL_BAUD_28800 4
+#define DL_BAUD_38400 3
+#define DL_BAUD_57600 2
+#define DL_BAUD_115200 1
+
+/*
+** Modem Control Register
+*/
+#define UA4_MCR (UA4_PORT + 4)
+#define UA4_MODEM_CTL UA4_MCR
+
+#define UA4_MCR_DTR 0x01 // Data Terminal Ready
+#define UA4_MCR_RTS 0x02 // Ready to Send
+#define UA4_MCR_RILP 0x04 // Loopback Interrupt Request
+#define UA4_MCR_ISEN 0x08 // Interrupt Signal Enable
+#define UA4_MCR_DCDLP 0x08 // DCD Loopback
+#define UA4_MCR_LOOP 0x10 // Loopback Enable
+
+// aliases
+#define UA4_MCR_DATA_TERMINAL_READY UA4_MCR_DTR
+#define UA4_MCR_READY_TO_SEND UA4_MCR_RTS
+#define UA4_MCR_LOOPBACK_INT_REQ UA4_MCR_RILP
+#define UA4_MCR_INT_SIGNAL_ENABLE UA4_MCR_ISEN
+#define UA4_MCR_LOOPBACK_DCD UA4_MCR_DCDLP
+#define UA4_MCR_LOOPBACK_ENABLE UA4_MCR_LOOP
+
+/*
+** Line Status Register
+*/
+#define UA4_LSR (UA4_PORT + 5)
+#define UA4_LINE_STATUS UA4_LSR
+
+#define UA4_LSR_RXDA 0x01 // Receiver Data Available
+#define UA4_LSR_OE 0x02 // Overrun Error
+#define UA4_LSR_PE 0x04 // Parity Error
+#define UA4_LSR_FE 0x08 // Framing Error
+#define UA4_LSR_BRK 0x10 // Break Event Detected
+#define UA4_LSR_TXRDY 0x20 // Transmitter Ready
+#define UA4_LSR_TXEMP 0x40 // Transmitter Empty
+#define UA4_LSR_ER_INF 0x80 // Error in RX_FIFO
+
+// aliases
+#define UA4_LSR_RX_DATA_AVAILABLE UA4_LSR_RXDA
+#define UA4_LSR_OVERRUN_ERROR UA4_LSR_OE
+#define UA4_LSR_PARITY_ERROR UA4_LSR_PE
+#define UA4_LSR_FRAMING_ERROR UA4_LSR_FE
+#define UA4_LSR_BREAK_DETECTED UA4_LSR_BRK
+#define UA4_LSR_TX_READY UA4_LSR_TXRDY
+#define UA4_LSR_TX_EMPTY UA4_LSR_TXEMP
+#define UA4_LSR_RX_FIFO_ERROR UA4_LSR_ER_INF
+
+/*
+** Modem Status Register
+*/
+#define UA4_MSR (UA4_PORT + 6)
+#define UA4_MODEM_STATUS UA4_MSR
+
+#define UA4_MSR_DCTS 0x01 // Delta Clear to Send
+#define UA4_MSR_DDSR 0x02 // Delta Data Set Ready
+#define UA4_MSR_TERI 0x04 // Trailing Edge Ring Indicate
+#define UA4_MSR_DDCD 0x08 // Delta Data Carrier Detect
+#define UA4_MSR_CTS 0x10 // Clear to Send
+#define UA4_MSR_DSR 0x20 // Data Set Ready
+#define UA4_MSR_RI 0x40 // Ring Indicate
+#define UA4_MSR_DCD 0x80 // Data Carrier Detect
+
+// aliases
+#define UA4_MSR_DELTA_CLEAR_TO_SEND UA4_MSR_DCTS
+#define UA4_MSR_DELTA_DATA_SET_READY UA4_MSR_DDSR
+#define UA4_MSR_TRAILING_EDGE_RING UA4_MSR_TERI
+#define UA4_MSR_DELTA_DATA_CARRIER_DETECT UA4_MSR_DDCD
+#define UA4_MSR_CLEAR_TO_SEND UA4_MSR_CTS
+#define UA4_MSR_DATA_SET_READY UA4_MSR_DSR
+#define UA4_MSR_RING_INDICATE UA4_MSR_RI
+#define UA4_MSR_DATA_CARRIER_DETECT UA4_MSR_DCD
+
+/*
+** Scratch Register
+**
+** Not used by the UART; usable as a "scratchpad" register for
+** temporary storage.
+*/
+#define UA4_SCR (UA4_PORT + 7)
+#define UA4_SCRATCH UA4_UA5_SCR
+
+#endif /* uart.h */
diff --git a/kernel/isrs.S b/kernel/old/isrs.S
index f5fdbca..f5fdbca 100644
--- a/kernel/isrs.S
+++ b/kernel/old/isrs.S
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;
+}
diff --git a/kernel/kmem.c b/kernel/old/kmem.c
index fe0c7de..fe0c7de 100644
--- a/kernel/kmem.c
+++ b/kernel/old/kmem.c
diff --git a/kernel/list.c b/kernel/old/list.c
index 5492615..5492615 100644
--- a/kernel/list.c
+++ b/kernel/old/list.c
diff --git a/kernel/procs.c b/kernel/old/procs.c
index 82c4c98..82c4c98 100644
--- a/kernel/procs.c
+++ b/kernel/old/procs.c
diff --git a/kernel/support.c b/kernel/old/support.c
index 89834ee..89834ee 100644
--- a/kernel/support.c
+++ b/kernel/old/support.c
diff --git a/kernel/syscalls.c b/kernel/old/syscalls.c
index 92a0a23..92a0a23 100644
--- a/kernel/syscalls.c
+++ b/kernel/old/syscalls.c
diff --git a/kernel/user.c b/kernel/old/user.c
index 5759534..5759534 100644
--- a/kernel/user.c
+++ b/kernel/old/user.c
diff --git a/kernel/vm.c b/kernel/old/vm.c
index 814ff12..814ff12 100644
--- a/kernel/vm.c
+++ b/kernel/old/vm.c
diff --git a/kernel/vmtables.c b/kernel/old/vmtables.c
index 113fd8b..113fd8b 100644
--- a/kernel/vmtables.c
+++ b/kernel/old/vmtables.c
diff --git a/kernel/startup.S b/kernel/startup.S
deleted file mode 100644
index 94b93b0..0000000
--- a/kernel/startup.S
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-** @file startup.S
-**
-** @author Jon Coles
-** @authors Warren R. Carithers, K. Reek
-**
-** SP startup code.
-**
-** This code prepares the various registers for execution of
-** the program. It sets up all the segment registers and the
-** runtime stack. By the time this code is running, we're in
-** protected mode already.
-*/
-
-#define KERNEL_SRC
-#define ASM_SRC
-
-# .arch i386
-
-#include <common.h>
-#include <bootstrap.h>
-#include <x86/arch.h>
-#include <x86/bios.h>
-#include <vm.h>
-
-/*
-** Configuration options - define in Makefile
-**
-** CLEAR_BSS include code to clear all BSS space
-** OS_CONFIG OS-related (vs. just standalone) variations
-*/
-
-/*
-** A symbol for locating the beginning of the code.
-*/
- .text
-
- .globl begtext
- .globl _start
-_start = V2PNC(begtext)
-
-/*
-** The entry point. When we get here, we have just entered protected
-** mode, so all the segment registers are incorrect except for CS.
-*/
-begtext:
-
- cli /* seems to be reset on entry to p. mode */
- movb $NMI_ENABLE, %al /* re-enable NMIs (bootstrap */
- outb $CMOS_ADDR /* turned them off) */
-
-/*
-** Set the data and stack segment registers (code segment register
-** was set by the long jump that switched us into protected mode).
-*/
- xorl %eax, %eax /* clear EAX */
- movw $GDT_DATA, %ax /* GDT entry #3 - data segment */
- movw %ax, %ds /* for all four data segment registers */
- movw %ax, %es
- movw %ax, %fs
- movw %ax, %gs
-
- movw $GDT_STACK, %ax /* entry #4 is the stack segment */
- movw %ax, %ss
-
- movl $TARGET_STACK, %esp /* set up the system stack pointer */
-
-#ifdef CLEAR_BSS
-/*
-** Zero the BSS segment
-**
-** These symbols are defined automatically by the linker, but they're
-** defined at their virtual addresses rather than their physical addresses,
-** and we haven't enabled paging yet.
-*/
- .globl __bss_start, _end
-
- movl $V2PNC(__bss_start), %edi
-clearbss:
- movl $0, (%edi)
- addl $4, %edi
- cmpl $V2PNC(_end), %edi
- jb clearbss
-#endif /* CLEAR_BSS */
-
-/*
-** Enable paging. We use "large" pages for the initial page directory
-** so that a one-level hierarchy will work for us. Once we have set
-** up our memory freelist, we'll create a two-level hierarchy using
-** "normal" 4KB pages.
-*/
- # enable large pages
- movl %cr4, %eax
- orl $(CR4_PSE), %eax
- movl %eax, %cr4
-
- # set the page directory
- .globl firstpdir
- movl $(V2PNC(firstpdir)), %eax
- movl %eax, %cr3
-
- # turn on paging
- movl %cr0, %eax
- orl $(CR0_PG), %eax
- movl %eax, %cr0
-
- # reset our stack pointer
- movl $(kstack + SZ_KSTACK), %esp
-
- # set the initial frame pointer
- xorl %ebp, %ebp
-
- # now, jump and switch into using high addresses
- # we use an indirect jump here because the assembler
- # would ordinarily generate a PC-relative target
- # address for the jump, which would not have the
- # desired effect
- movl $onward, %eax
- jmp *%eax
-
-onward:
-
-/*
-** Call the system initialization routine.
-**
-** Alternate idea: push the address of isr_restore
-** and just do an indirect jump?
-*/
- .globl main
-
- movl $main, %eax
- call *%eax
-
-/*
-** At this point, main() must have created the first user
-** process, and we're ready to shift into user mode. The user
-** stack for that process must have the initial context in it;
-** we treat this as a "return from interrupt" event, and just
-** transfer to the code that restores the user context.
-*/
-
- .globl isr_restore
- jmp isr_restore
-
- .data
-
-/*
-** Define the kernel stack here, at a multiple-of-16 address
-*/
- .p2align 4
- .globl kstack
-kstack: .space SZ_KSTACK, 0
-
-/*
-** Define the initial kernel ESP here, as well. It should point
-** to the first byte after the stack.
-*/
-
- .globl kernel_esp
-kernel_esp:
- .long kstack + SZ_KSTACK