update for mooc OS labs
This commit is contained in:
@@ -8,9 +8,9 @@
|
||||
#include <clock.h>
|
||||
#include <intr.h>
|
||||
#include <pmm.h>
|
||||
|
||||
#include <kmonitor.h>
|
||||
int kern_init(void) __attribute__((noreturn));
|
||||
|
||||
void grade_backtrace(void);
|
||||
static void lab1_switch_test(void);
|
||||
|
||||
int
|
||||
@@ -37,7 +37,7 @@ kern_init(void) {
|
||||
|
||||
//LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test()
|
||||
// user/kernel mode switch test
|
||||
//lab1_switch_test();
|
||||
lab1_switch_test();
|
||||
|
||||
/* do nothing */
|
||||
while (1);
|
||||
@@ -84,11 +84,24 @@ lab1_print_cur_status(void) {
|
||||
static void
|
||||
lab1_switch_to_user(void) {
|
||||
//LAB1 CHALLENGE 1 : TODO
|
||||
asm volatile (
|
||||
"sub $0x8, %%esp \n"
|
||||
"int %0 \n"
|
||||
"movl %%ebp, %%esp"
|
||||
:
|
||||
: "i"(T_SWITCH_TOU)
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
lab1_switch_to_kernel(void) {
|
||||
//LAB1 CHALLENGE 1 : TODO
|
||||
asm volatile (
|
||||
"int %0 \n"
|
||||
"movl %%ebp, %%esp \n"
|
||||
:
|
||||
: "i"(T_SWITCH_TOK)
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <assert.h>
|
||||
#include <console.h>
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <string.h>
|
||||
#define TICK_NUM 100
|
||||
|
||||
static void print_ticks() {
|
||||
@@ -51,6 +51,9 @@ idt_init(void) {
|
||||
for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) {
|
||||
SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL);
|
||||
}
|
||||
// set for switch from user to kernel
|
||||
SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER);
|
||||
// load the IDT
|
||||
lidt(&idt_pd);
|
||||
}
|
||||
|
||||
@@ -140,6 +143,9 @@ print_regs(struct pushregs *regs) {
|
||||
cprintf(" eax 0x%08x\n", regs->reg_eax);
|
||||
}
|
||||
|
||||
/* temporary trapframe or pointer to trapframe */
|
||||
struct trapframe switchk2u, *switchu2k;
|
||||
|
||||
/* trap_dispatch - dispatch based on what type of trap occurred */
|
||||
static void
|
||||
trap_dispatch(struct trapframe *tf) {
|
||||
@@ -168,8 +174,30 @@ trap_dispatch(struct trapframe *tf) {
|
||||
break;
|
||||
//LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes.
|
||||
case T_SWITCH_TOU:
|
||||
if (tf->tf_cs != USER_CS) {
|
||||
switchk2u = *tf;
|
||||
switchk2u.tf_cs = USER_CS;
|
||||
switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS;
|
||||
switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8;
|
||||
|
||||
// set eflags, make sure ucore can use io under user mode.
|
||||
// if CPL > IOPL, then cpu will generate a general protection.
|
||||
switchk2u.tf_eflags |= FL_IOPL_MASK;
|
||||
|
||||
// set temporary stack
|
||||
// then iret will jump to the right stack
|
||||
*((uint32_t *)tf - 1) = (uint32_t)&switchk2u;
|
||||
}
|
||||
break;
|
||||
case T_SWITCH_TOK:
|
||||
panic("T_SWITCH_** ??\n");
|
||||
if (tf->tf_cs != KERNEL_CS) {
|
||||
tf->tf_cs = KERNEL_CS;
|
||||
tf->tf_ds = tf->tf_es = KERNEL_DS;
|
||||
tf->tf_eflags &= ~FL_IOPL_MASK;
|
||||
switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8));
|
||||
memmove(switchu2k, tf, sizeof(struct trapframe) - 8);
|
||||
*((uint32_t *)tf - 1) = (uint32_t)switchu2k;
|
||||
}
|
||||
break;
|
||||
case IRQ_OFFSET + IRQ_IDE1:
|
||||
case IRQ_OFFSET + IRQ_IDE2:
|
||||
|
||||
Reference in New Issue
Block a user