Merge branch 'lab3' into lab4

This commit is contained in:
Danila Fedorin 2019-04-24 13:57:20 -07:00
commit c3e2a92b08
16 changed files with 526 additions and 45 deletions

View File

@ -17,6 +17,7 @@ KERN_SRCFILES := kern/entry.S \
kern/entrypgdir.c \
kern/init.c \
kern/console.c \
kern/ansi.c \
kern/monitor.c \
kern/pmap.c \
kern/env.c \

49
kern/ansi.c Normal file
View File

@ -0,0 +1,49 @@
#include <kern/ansi.h>
uint8_t vga_colors[8] = {
[0] = 0,
[1] = 4,
[2] = 2,
[3] = 6,
[4] = 1,
[5] = 5,
[6] = 3,
[7] = 7
};
void
ansi_step(void (*putcf)(int), int c, struct AttrState* s) {
switch(s->state) {
case NORMAL:
if(c != 27) putcf(c | (s->cattrs << 8));
else s->state = ESC;
return;
case ESC:
s->state = (c == '[') ? BRACKET : NORMAL;
return;
case BRACKET:
if(c == '3') {
s->state = COLOR_FG;
} else if(c == '0') {
s->state = COLOR;
s->attrs = 0;
} else {
s->state = NORMAL;
}
return;
case COLOR_FG:
if(c >= '0' && c <= '9') {
s->attrs = (s->attrs & ~(0x07)) | vga_colors[c - '0'];
c |= ((c - '0') << 8);
s->state = COLOR;
} else {
s->state = NORMAL;
}
return;
case COLOR:
s->state = (c == ';') ? BRACKET : NORMAL;
if(c == 'm') s->cattrs = s->attrs;
return;
}
}

36
kern/ansi.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef _ANSI_H_
#define _ANSI_H_
#include <inc/types.h>
#define ACOL_WRAP(s) "\33[" s "m"
#define ACOL_BLACK ACOL_WRAP("30")
#define ACOL_RED ACOL_WRAP("31")
#define ACOL_GREEN ACOL_WRAP("32")
#define ACOL_YELLOW ACOL_WRAP("33")
#define ACOL_BLUE ACOL_WRAP("34")
#define ACOL_MAGENTA ACOL_WRAP("35")
#define ACOL_CYAN ACOL_WRAP("36")
#define ACOL_WHITE ACOL_WRAP("37")
#define ACOL_CLEAR ACOL_WRAP("0")
#define ACOL_TAG(c, s) "[" c s ACOL_CLEAR "] "
#define ACOL_NOTE(s) ACOL_TAG(ACOL_WHITE, " Note ") s
#define ACOL_WARN(s) ACOL_TAG(ACOL_YELLOW, "Warning") s
#define ACOL_ERR(s) ACOL_TAG(ACOL_RED, " Error ") s
struct AttrState {
uint8_t cattrs;
uint8_t attrs;
enum {
NORMAL,
ESC,
BRACKET,
COLOR_FG,
COLOR
} state;
};
void ansi_step(void (*putcf)(int), int c, struct AttrState* s);
#endif

View File

@ -9,6 +9,7 @@
#include <kern/console.h>
#include <kern/trap.h>
#include <kern/picirq.h>
#include <kern/ansi.h>
static void cons_intr(int (*proc)(void));
static void cons_putc(int c);
@ -130,6 +131,7 @@ lpt_putc(int c)
static unsigned addr_6845;
static uint16_t *crt_buf;
static uint16_t crt_pos;
static struct AttrState attst;
static void
cga_init(void)
@ -138,6 +140,10 @@ cga_init(void)
uint16_t was;
unsigned pos;
attst.cattrs = 0;
attst.attrs = 0;
attst.state = NORMAL;
cp = (uint16_t*) (KERNBASE + CGA_BUF);
was = *cp;
*cp = (uint16_t) 0xA55A;
@ -159,10 +165,15 @@ cga_init(void)
crt_pos = pos;
}
static void cga_putc_internal(int c);
static void
cga_putc(int c)
cga_putc(int c){
ansi_step(cga_putc_internal, c, &attst);
}
static void
cga_putc_internal(int c)
{
// if no attribute given, then use black on white
if (!(c & ~0xFF))

View File

@ -119,6 +119,13 @@ env_init(void)
{
// Set up envs array
// LAB 3: Your code here.
size_t i = NENV;
while(true) {
i--;
envs[i].env_link = env_free_list;
env_free_list = &envs[i];
if(i == 0) break;
}
// Per-CPU part of the initialization
env_init_percpu();
@ -180,8 +187,9 @@ env_setup_vm(struct Env *e)
// is an exception -- you need to increment env_pgdir's
// pp_ref for env_free to work correctly.
// - The functions in kern/pmap.h are handy.
// LAB 3: Your code here.
p->pp_ref++;
e->env_pgdir = page2kva(p);
memcpy(e->env_pgdir + PDX(UTOP), kern_pgdir + PDX(UTOP), sizeof(pde_t) * (NPDENTRIES - PDX(UTOP)));
// UVPT maps the env's own page table read-only.
// Permissions: kernel R, user R
@ -279,6 +287,17 @@ region_alloc(struct Env *e, void *va, size_t len)
// 'va' and 'len' values that are not page-aligned.
// You should round va down, and round (va + len) up.
// (Watch out for corner-cases!)
va = ROUNDDOWN(va, PGSIZE);
size_t count = ROUNDUP(len, PGSIZE) / PGSIZE;
struct PageInfo* p;
while(count--) {
if(!(p = page_alloc(0)))
panic("Failed to allocate memory");
if(page_insert(e->env_pgdir, p, va, PTE_U | PTE_W))
panic("Failed to allocate memory for page table");
va += PGSIZE;
}
}
//
@ -336,10 +355,24 @@ load_icode(struct Env *e, uint8_t *binary)
// LAB 3: Your code here.
// TODO validate the headers
struct Elf* elf = (struct Elf*) binary;
struct Proghdr* ph = (struct Proghdr*) (binary + elf->e_phoff);
struct Proghdr* phend = ph + elf->e_phnum;
for(; ph < phend; ph++) {
if(ph->p_type != ELF_PROG_LOAD) continue;
region_alloc(e, (void*) ph->p_va, ph->p_memsz);
lcr3(PADDR(e->env_pgdir));
memcpy((void*) ph->p_va, binary + ph->p_offset, ph->p_filesz);
memset((void*) ph->p_va + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
lcr3(PADDR(kern_pgdir));
}
e->env_tf.tf_eip = elf->e_entry;
// Now map one page for the program's initial stack
// at virtual address USTACKTOP - PGSIZE.
// LAB 3: Your code here.
region_alloc(e, (void*) USTACKTOP - PGSIZE, PGSIZE);
}
//
@ -353,6 +386,11 @@ void
env_create(uint8_t *binary, enum EnvType type)
{
// LAB 3: Your code here.
struct Env* new_env;
if(env_alloc(&new_env, 0) < 0)
panic("Failed to allocate environment");
new_env->env_type = type;
load_icode(new_env, binary);
}
//
@ -483,7 +521,13 @@ env_run(struct Env *e)
// e->env_tf to sensible values.
// LAB 3: Your code here.
panic("env_run not yet implemented");
if(curenv && curenv->env_status == ENV_RUNNING) {
curenv->env_status = ENV_RUNNABLE;
}
curenv = e;
e->env_status = ENV_RUNNING;
e->env_runs++;
lcr3(PADDR(e->env_pgdir));
env_pop_tf(&e->env_tf);
}

View File

@ -26,6 +26,12 @@ i386_init(void)
cons_init();
cprintf("444544 decimal is %o octal!\n", 444544);
cprintf("\33[31m" "C"
"\33[33m" "o"
"\33[32m" "l"
"\33[36m" "o"
"\33[34m" "r"
"\33[0m" " Works!" "\n");
// Lab 2 memory management initialization functions
mem_init();

View File

@ -196,7 +196,8 @@ debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info)
// Search within [lline, rline] for the line number stab.
// If found, set info->eip_line to the right line number.
// If found, set info->eip_line to the correct line number.
// e.g., info->eip_line = stabs[lline].n_desc
// If not found, return -1.
//
// Hint:
@ -204,6 +205,12 @@ debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info)
// Look at the STABS documentation and <inc/stab.h> to find
// which one.
// Your code here.
stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
if(lline <= rline) {
info->eip_line = stabs[lline].n_desc;
} else {
info->eip_line = -1;
}
// Search backwards from the line number for the relevant filename

View File

@ -7,10 +7,13 @@
#include <inc/assert.h>
#include <inc/x86.h>
#include <kern/ansi.h>
#include <kern/console.h>
#include <kern/monitor.h>
#include <kern/kdebug.h>
#include <kern/trap.h>
#include <kern/pmap.h>
#include <inc/string.h>
#define CMDBUF_SIZE 80 // enough for one VGA text line
@ -26,6 +29,10 @@ struct Command {
static struct Command commands[] = {
{ "help", "Display this list of commands", mon_help },
{ "kerninfo", "Display information about the kernel", mon_kerninfo },
{ "backtrace", "Display current backtrace", mon_backtrace },
{ "showmappings", "Display the physical mappings for range", mon_showmappings },
{ "mperms", "Change the permissions of a memory range", mon_mperms }
};
/***** Implementations of basic kernel monitor commands *****/
@ -46,7 +53,7 @@ mon_kerninfo(int argc, char **argv, struct Trapframe *tf)
extern char _start[], entry[], etext[], edata[], end[];
cprintf("Special kernel symbols:\n");
cprintf(" _start %08x (phys)\n", _start);
cprintf(" _start %08x (phys)\n", _start);
cprintf(" entry %08x (virt) %08x (phys)\n", entry, entry - KERNBASE);
cprintf(" etext %08x (virt) %08x (phys)\n", etext, etext - KERNBASE);
cprintf(" edata %08x (virt) %08x (phys)\n", edata, edata - KERNBASE);
@ -62,10 +69,124 @@ mon_backtrace(int argc, char **argv, struct Trapframe *tf)
// LAB 1: Your code here.
// HINT 1: use read_ebp().
// HINT 2: print the current ebp on the first line (not current_ebp[0])
uint32_t* ebp;
uint32_t eip;
struct Eipdebuginfo info;
ebp = (uint32_t*) read_ebp();
cprintf("Stack backtrace:\n");
while(ebp) {
eip = ebp[1];
cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n",
ebp, eip, ebp[2], ebp[3], ebp[4], ebp[5], ebp[6]);
ebp = (uint32_t*) ebp[0];
debuginfo_eip(eip, &info);
cprintf(" %s:%d: %.*s+%d\n",
info.eip_file, info.eip_line,
info.eip_fn_namelen, info.eip_fn_name,
eip - info.eip_fn_addr);
};
return 0;
}
#define EXPECT_ARGS(n, ac) if(ac - 1 != n) { \
cprintf(ACOL_ERR("Expected %d arguments, " \
"got %d\n"), n, ac - 1); \
return 1; }
#define VA_TXT ACOL_CYAN "VA" ACOL_CLEAR
#define PA_TXT ACOL_GREEN "PA" ACOL_CLEAR
char*
decode_pte_perms(pte_t pte, char* buffer) {
buffer[0] = (pte & PTE_W) ? 'w' : 'r';
buffer[1] = (pte & PTE_U) ? 'u' : 'k';
return buffer;
}
void
get_pagebounds(char* one, char* two, uintptr_t* pone, uintptr_t* ptwo) {
long from = strtol(one, NULL, 0);
long to = strtol(two, NULL, 0);
*pone = ROUNDDOWN(from, PGSIZE);
*ptwo = ROUNDUP(to, PGSIZE);
if(*pone != from) cprintf(ACOL_WARN("Aligning start address %p down to %p\n"),
from, *pone);
if(*ptwo != to) cprintf(ACOL_WARN("Aligning end address %p up to %p\n"),
to, *ptwo);
}
int
mon_showmappings(int argc, char** argv, struct Trapframe* tf) {
EXPECT_ARGS(2, argc);
uintptr_t va_start, va_end;
char buffer[3] = {0};
get_pagebounds(argv[1], argv[2], &va_start, &va_end);
if(va_start == va_end) va_end += PGSIZE;
while(va_start < va_end) {
pte_t* pte = pgdir_walk(kern_pgdir, (const void*) va_start, 0);
cprintf(VA_TXT " 0x%08p -> ", va_start);
if(pte && (*pte & PTE_P)) {
cprintf(PA_TXT " 0x%08p (%s)\n", PTE_ADDR(*pte),
decode_pte_perms(*pte, buffer));
} else {
cprintf(PA_TXT " ------------\n");
}
va_start += PGSIZE;
}
return 0;
}
int mon_mperms(int argc, char** argv, struct Trapframe* tf) {
EXPECT_ARGS(3, argc);
pte_t perms = 0;
enum {
PERM_ADD,
PERM_REMOVE,
PERM_SET
} pmode;
const char* str = argv[1];
if(str[0] == '+') { pmode = PERM_ADD; str++; }
else if(str[0] == '-') { pmode = PERM_REMOVE; str++; }
else pmode = PERM_SET;
while(*str) {
if(*str == 'w') perms |= PTE_W;
else if(*str == 'u') perms |= PTE_U;
else {
cprintf(ACOL_ERR("Unknown permission character %c\n"), *str);
return 1;
}
str++;
}
uintptr_t va_start, va_end;
get_pagebounds(argv[2], argv[3], &va_start, &va_end);
if(va_start == va_end) va_end += PGSIZE;
while(va_start < va_end) {
pte_t* pte = pgdir_walk(kern_pgdir, (void*) va_start, 0);
if(!pte || !(*pte & PTE_P)) { va_start += PGSIZE; continue; }
if(pmode == PERM_ADD) {
*pte |= perms;
} else if(pmode == PERM_REMOVE) {
*pte &= ~perms;
} else if(pmode == PERM_SET) {
*pte = PTE_ADDR(*pte) | perms | PTE_P;
}
va_start += PGSIZE;
}
return 0;
}
/***** Kernel monitor command interpreter *****/

View File

@ -15,5 +15,7 @@ void monitor(struct Trapframe *tf);
int mon_help(int argc, char **argv, struct Trapframe *tf);
int mon_kerninfo(int argc, char **argv, struct Trapframe *tf);
int mon_backtrace(int argc, char **argv, struct Trapframe *tf);
int mon_showmappings(int argc, char **argv, struct Trapframe *tf);
int mon_mperms(int argc, char** argv, struct Trapframe* tf);
#endif // !JOS_KERN_MONITOR_H

View File

@ -6,6 +6,7 @@
#include <inc/string.h>
#include <inc/assert.h>
#include <kern/monitor.h>
#include <kern/pmap.h>
#include <kern/kclock.h>
#include <kern/env.h>
@ -105,8 +106,10 @@ boot_alloc(uint32_t n)
// to a multiple of PGSIZE.
//
// LAB 2: Your code here.
result = nextfree;
nextfree = ROUNDUP(nextfree + n, PGSIZE);
return NULL;
return result;
}
// Set up a two-level page table:
@ -127,9 +130,6 @@ mem_init(void)
// Find out how much memory the machine has (npages & npages_basemem).
i386_detect_memory();
// Remove this line when you're ready to test this function.
panic("mem_init: This function is not finished\n");
//////////////////////////////////////////////////////////////////////
// create initial page directory.
kern_pgdir = (pde_t *) boot_alloc(PGSIZE);
@ -151,11 +151,16 @@ mem_init(void)
// array. 'npages' is the number of physical pages in memory. Use memset
// to initialize all fields of each struct PageInfo to 0.
// Your code goes here:
size_t pages_size = sizeof(struct PageInfo) * npages;
pages = boot_alloc(pages_size);
memset(pages, 0, pages_size);
//////////////////////////////////////////////////////////////////////
// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
// LAB 3: Your code here.
size_t envs_size = sizeof(struct Env) * NENV;
envs = boot_alloc(envs_size);
memset(envs, 0, envs_size);
//////////////////////////////////////////////////////////////////////
// Now that we've allocated the initial kernel data structures, we set
@ -179,6 +184,11 @@ mem_init(void)
// (ie. perm = PTE_U | PTE_P)
// - pages itself -- kernel RW, user NONE
// Your code goes here:
boot_map_region(kern_pgdir,
UPAGES, ROUNDUP(pages_size, PGSIZE),
PADDR(pages), PTE_U);
kern_pgdir[PDX(UPAGES)] |= PTE_U;
kern_pgdir[PDX(UPAGES)] &= ~PTE_W;
//////////////////////////////////////////////////////////////////////
// Map the 'envs' array read-only by the user at linear address UENVS
@ -187,6 +197,11 @@ mem_init(void)
// - the new image at UENVS -- kernel R, user R
// - envs itself -- kernel RW, user NONE
// LAB 3: Your code here.
boot_map_region(kern_pgdir,
UENVS, ROUNDUP(envs_size, PGSIZE),
PADDR(envs), PTE_U);
kern_pgdir[PDX(UENVS)] |= PTE_U;
kern_pgdir[PDX(UPAGES)] &= ~PTE_W;
//////////////////////////////////////////////////////////////////////
// Use the physical memory that 'bootstack' refers to as the kernel
@ -199,6 +214,11 @@ mem_init(void)
// overwrite memory. Known as a "guard page".
// Permissions: kernel RW, user NONE
// Your code goes here:
boot_map_region(kern_pgdir,
KSTACKTOP-KSTKSIZE, KSTKSIZE,
PADDR(bootstack), PTE_W);
kern_pgdir[PDX(KSTACKTOP-KSTKSIZE)] |= PTE_W;
kern_pgdir[PDX(KSTACKTOP-KSTKSIZE)] &= ~PTE_U;
//////////////////////////////////////////////////////////////////////
// Map all of physical memory at KERNBASE.
@ -208,6 +228,12 @@ mem_init(void)
// we just set up the mapping anyway.
// Permissions: kernel RW, user NONE
// Your code goes here:
boot_map_region(kern_pgdir,
KERNBASE, 0x100000000 - KERNBASE,
0, PTE_W);
kern_pgdir[PDX(KERNBASE)] |= PTE_W | PTE_P;
kern_pgdir[PDX(KERNBASE)] &= ~PTE_U;
// Initialize the SMP-related parts of the memory map
mem_init_mp();
@ -267,6 +293,14 @@ mem_init_mp(void)
// The 'pages' array has one 'struct PageInfo' entry per physical page.
// Pages are reference counted, and free pages are kept on a linked list.
// --------------------------------------------------------------
bool
is_reserved(size_t pagenum) {
if(pagenum == 0) return true;
if(pagenum >= PGNUM(IOPHYSMEM) &&
pagenum < PGNUM(PADDR(boot_alloc(0)))) return true;
return false;
}
//
// Initialize page structure and memory free list.
@ -300,9 +334,13 @@ page_init(void)
// free pages!
size_t i;
for (i = 0; i < npages; i++) {
pages[i].pp_ref = 0;
pages[i].pp_link = page_free_list;
page_free_list = &pages[i];
if(is_reserved(i)) {
pages[i].pp_ref = 1;
} else {
pages[i].pp_ref = 0;
pages[i].pp_link = page_free_list;
page_free_list = &pages[i];
}
}
}
@ -321,8 +359,17 @@ page_init(void)
struct PageInfo *
page_alloc(int alloc_flags)
{
// Fill this function in
return 0;
struct PageInfo* to_return = page_free_list;
if(to_return == 0) return NULL;
page_free_list = to_return->pp_link;
to_return->pp_link = NULL;
if(alloc_flags & ALLOC_ZERO) {
memset(page2kva(to_return), 0, PGSIZE);
}
return to_return;
}
//
@ -332,9 +379,10 @@ page_alloc(int alloc_flags)
void
page_free(struct PageInfo *pp)
{
// Fill this function in
// Hint: You may want to panic if pp->pp_ref is nonzero or
// pp->pp_link is not NULL.
if(pp->pp_ref || pp->pp_link != NULL)
panic("Freeing page with nonzero reference count!");
pp->pp_link = page_free_list;
page_free_list = pp;
}
//
@ -373,8 +421,25 @@ page_decref(struct PageInfo* pp)
pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
pte_t* base_table = NULL;
if(pgdir[PDX(va)] & PTE_P) {
// We have a valid page table; awesome!
base_table = KADDR(PTE_ADDR(pgdir[PDX(va)]));
} else {
if(!create) return NULL;
struct PageInfo* page = page_alloc(ALLOC_ZERO);
if(!page) return NULL;
page->pp_ref++;
physaddr_t ppa = page2pa(page);
pgdir[PDX(va)] = ppa | PTE_P | PTE_U | PTE_W;
base_table = KADDR(ppa);
}
// Fill this function in
return NULL;
return &base_table[PTX(va)];
}
//
@ -391,7 +456,16 @@ pgdir_walk(pde_t *pgdir, const void *va, int create)
static void
boot_map_region(pde_t *pgdir, uintptr_t va, size_t size, physaddr_t pa, int perm)
{
// Fill this function in
size_t count = size / PGSIZE;
uintptr_t start_va = va;
physaddr_t start_pa = pa;
while(count-- && start_va <= va && start_pa <= pa) {
pte_t* pte = pgdir_walk(pgdir, (void*) va, true);
*pte = pa | perm | PTE_P;
va += PGSIZE;
pa += PGSIZE;
}
}
//
@ -422,7 +496,14 @@ boot_map_region(pde_t *pgdir, uintptr_t va, size_t size, physaddr_t pa, int perm
int
page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
{
// Fill this function in
pte_t* pte;
if(!(pte = pgdir_walk(pgdir, va, true))) return -E_NO_MEM;
pp->pp_ref++;
if(*pte & PTE_P) page_remove(pgdir, va);
*pte = page2pa(pp) | PTE_P | perm;
tlb_invalidate(pgdir, va);
return 0;
}
@ -440,8 +521,15 @@ page_insert(pde_t *pgdir, struct PageInfo *pp, void *va, int perm)
struct PageInfo *
page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
{
// Fill this function in
return NULL;
pte_t* pte;
if(!(pte = pgdir_walk(pgdir, va, false))) {
if(pte_store) *pte_store = NULL;
return NULL;
}
struct PageInfo* pp = pa2page(PTE_ADDR(*pte));
if(pte_store) *pte_store = pte;
return pp;
}
//
@ -462,7 +550,15 @@ page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
void
page_remove(pde_t *pgdir, void *va)
{
// Fill this function in
pte_t* pte;
struct PageInfo* pp;
pp = page_lookup(pgdir, va, &pte);
if(!(*pte & PTE_P)) return;
if(!(--(pp->pp_ref))) page_free(pp);
*pte = 0;
tlb_invalidate(pgdir, va);
}
//
@ -536,6 +632,23 @@ int
user_mem_check(struct Env *env, const void *va, size_t len, int perm)
{
// LAB 3: Your code here.
uintptr_t to_report = (uintptr_t) va;
const char* bottom = ROUNDDOWN(va, PGSIZE);
size_t aligned_count = ROUNDUP(len, PGSIZE) / PGSIZE;
pde_t mask = PTE_P | PTE_U | PTE_W;
pde_t perms = mask;
#define VALID ((perms & (perm | PTE_P)) == (perm | PTE_P))
#define DO_CHECK if(!VALID) { user_mem_check_addr = to_report; return -E_FAULT; }
while(aligned_count--) {
perms &= env->env_pgdir[PDX(bottom)] & mask;
DO_CHECK;
perms &= (*pgdir_walk(env->env_pgdir, bottom, 0)) & mask;
DO_CHECK;
bottom += PGSIZE;
to_report = (uintptr_t) bottom;
}
return 0;
}

View File

@ -20,9 +20,7 @@ sys_cputs(const char *s, size_t len)
{
// Check that the user has permission to read memory [s, s+len).
// Destroy the environment if not.
// LAB 3: Your code here.
user_mem_assert(curenv, s, len, 0);
// Print the string supplied by the user.
cprintf("%.*s", len, s);
}
@ -271,9 +269,16 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
// Return any appropriate return value.
// LAB 3: Your code here.
panic("syscall not implemented");
switch (syscallno) {
case SYS_cputs:
sys_cputs((const char*) a1, a2);
return 0;
case SYS_cgetc:
return sys_cgetc();
case SYS_getenvid:
return sys_getenvid();
case SYS_env_destroy:
return sys_env_destroy(a1);
default:
return -E_INVAL;
}

View File

@ -68,6 +68,26 @@ static const char *trapname(int trapno)
// XYZ: write a function declaration here...
// e.g., void t_divide();
void t_divide();
void t_debug();
void t_nmi();
void t_brkpt();
void t_oflow();
void t_bound();
void t_illop();
void t_device();
void t_dblflt();
void t_tss();
void t_segnp();
void t_stack();
void t_gpflt();
void t_pgflt();
void t_fperr();
void t_align();
void t_mchk();
void t_simderr();
void t_syscall();
void t_default();
void
trap_init(void)
@ -84,6 +104,26 @@ trap_init(void)
*
*/
// LAB 3: Your code here.
SETGATE(idt[T_DIVIDE], 0, GD_KT, t_divide, 0);
SETGATE(idt[T_DEBUG], 0, GD_KT, t_debug, 0);
SETGATE(idt[T_NMI], 0, GD_KT, t_nmi, 0);
SETGATE(idt[T_BRKPT], 0, GD_KT, t_brkpt, 3);
SETGATE(idt[T_OFLOW], 0, GD_KT, t_oflow, 0);
SETGATE(idt[T_BOUND], 0, GD_KT, t_bound, 0);
SETGATE(idt[T_ILLOP], 0, GD_KT, t_illop, 0);
SETGATE(idt[T_DEVICE], 0, GD_KT, t_device, 0);
SETGATE(idt[T_DBLFLT], 0, GD_KT, t_dblflt, 0);
SETGATE(idt[T_TSS], 0, GD_KT, t_tss, 0);
SETGATE(idt[T_SEGNP], 0, GD_KT, t_segnp, 0);
SETGATE(idt[T_STACK], 0, GD_KT, t_stack, 0);
SETGATE(idt[T_GPFLT], 0, GD_KT, t_gpflt, 0);
SETGATE(idt[T_PGFLT], 0, GD_KT, t_pgflt, 0);
SETGATE(idt[T_FPERR], 0, GD_KT, t_fperr, 0);
SETGATE(idt[T_ALIGN], 0, GD_KT, t_align, 0);
SETGATE(idt[T_MCHK], 0, GD_KT, t_mchk, 0);
SETGATE(idt[T_SIMDERR], 0, GD_KT, t_simderr, 0);
SETGATE(idt[T_SYSCALL], 0, GD_KT, t_syscall, 3);
SETGATE(idt[T_DEFAULT], 0, GD_KT, t_default, 0);
// Per-CPU setup
trap_init_percpu();
@ -188,6 +228,22 @@ trap_dispatch(struct Trapframe *tf)
{
// Handle processor exceptions.
// LAB 3: Your code here.
if (tf->tf_trapno == T_PGFLT) {
page_fault_handler(tf);
return;
} else if (tf->tf_trapno == T_BRKPT) {
monitor(tf);
return;
} else if (tf->tf_trapno == T_SYSCALL) {
int32_t returned = syscall(tf->tf_regs.reg_eax,
tf->tf_regs.reg_edx,
tf->tf_regs.reg_ecx,
tf->tf_regs.reg_ebx,
tf->tf_regs.reg_edi,
tf->tf_regs.reg_esi);
tf->tf_regs.reg_eax = returned;
return;
}
// Handle spurious interrupts
// The hardware sometimes raises these because of noise on the

View File

@ -47,6 +47,26 @@
/*
* Lab 3: Your code here for generating entry points for the different traps.
*/
TRAPHANDLER_NOEC(t_divide, T_DIVIDE);
TRAPHANDLER_NOEC(t_debug, T_DEBUG);
TRAPHANDLER_NOEC(t_nmi, T_NMI);
TRAPHANDLER_NOEC(t_brkpt, T_BRKPT);
TRAPHANDLER_NOEC(t_oflow, T_OFLOW);
TRAPHANDLER_NOEC(t_bound, T_OFLOW);
TRAPHANDLER_NOEC(t_illop, T_OFLOW);
TRAPHANDLER_NOEC(t_device, T_OFLOW);
TRAPHANDLER(t_dblflt, T_OFLOW);
TRAPHANDLER(t_tss, T_TSS);
TRAPHANDLER(t_segnp, T_SEGNP);
TRAPHANDLER(t_stack, T_STACK);
TRAPHANDLER(t_gpflt, T_GPFLT);
TRAPHANDLER(t_pgflt, T_PGFLT);
TRAPHANDLER_NOEC(t_fperr, T_FPERR);
TRAPHANDLER(t_align, T_ALIGN);
TRAPHANDLER_NOEC(t_mchk, T_MCHK);
TRAPHANDLER_NOEC(t_simderr, T_SIMDERR);
TRAPHANDLER_NOEC(t_syscall, T_SYSCALL);
TRAPHANDLER(t_default, T_DEFAULT);
// HINT 1 : TRAPHANDLER_NOEC(t_divide, T_DIVIDE);
// Do something like this if there is no error code for the trap
@ -59,4 +79,15 @@
* Lab 3: Your code here for _alltraps
*/
.globl _alltraps
_alltraps:
sub $0x2, %esp
pushw %ds
sub $0x2, %esp
pushw %es
pushal
mov $(GD_KD), %eax
movw %ax, %ds
movw %ax, %es
pushl %esp
call trap

View File

@ -13,7 +13,8 @@ libmain(int argc, char **argv)
{
// set thisenv to point at our Env structure in envs[].
// LAB 3: Your code here.
thisenv = 0;
envid_t id = sys_getenvid();
thisenv = &envs[ENVX(id)];
// save the name of the program so that panic() can use it
if (argc > 0)

View File

@ -207,11 +207,9 @@ vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
// (unsigned) octal
case 'o':
// LAB 1: Replace this with your code.
putch('X', putdat);
putch('X', putdat);
putch('X', putdat);
break;
num = getuint(&ap, lflag);
base = 8;
goto number;
// pointer
case 'p':

View File

@ -1,5 +1,5 @@
OSU ID (xxx-yyy-zzz) : 933456789
FLIP ID (e.g., jangye) : jangye
Name : Yeongjin Jang
OSU ID (xxx-yyy-zzz) : 932700867
FLIP ID (e.g., jangye) : fedorind
Name : Danila Fedorin
CS 444/544 ? : 444
Lab Class # : Lab 1
Lab Class # : Lab 2