mirror of
https://github.com/SmallPond/MIT6.828_OS.git
synced 2026-04-29 05:11:07 +08:00
my solution to lab5
This commit is contained in:
@@ -55,6 +55,7 @@ sys_env_destroy(envid_t envid)
|
||||
|
||||
if ((r = envid2env(envid, &e, 1)) < 0)
|
||||
return r;
|
||||
|
||||
if (e == curenv)
|
||||
cprintf("[%08x] exiting gracefully\n", curenv->env_id);
|
||||
else
|
||||
@@ -128,6 +129,38 @@ sys_env_set_status(envid_t envid, int status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set envid's trap frame to 'tf'.
|
||||
// tf is modified to make sure that user environments always run at code
|
||||
// protection level 3 (CPL 3), interrupts enabled, and IOPL of 0.
|
||||
//
|
||||
// Returns 0 on success, < 0 on error. Errors are:
|
||||
// -E_BAD_ENV if environment envid doesn't currently exist,
|
||||
// or the caller doesn't have permission to change envid.
|
||||
static int
|
||||
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
|
||||
{
|
||||
// LAB 5: Your code here.
|
||||
// Remember to check whether the user has supplied us with a good
|
||||
// address!
|
||||
struct Env *env;
|
||||
int r;
|
||||
if ( (r = envid2env(envid, &env, 1)) < 0)
|
||||
return r;
|
||||
|
||||
// 什么时候会出现没有权限访问的问题?
|
||||
user_mem_assert(env, tf, sizeof(struct Trapframe), PTE_U);
|
||||
// 直接整个结构体也是可以赋值的
|
||||
|
||||
// tf->tf_cs |= (GD_UT | 0x3);
|
||||
tf->tf_eflags |= FL_IF;
|
||||
// 普通进程无I/O权限
|
||||
tf->tf_eflags &= ~FL_IOPL_MASK;
|
||||
|
||||
env->env_tf = *tf;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
// Set the page fault upcall for 'envid' by modifying the corresponding struct
|
||||
// Env's 'env_pgfault_upcall' field. When 'envid' causes a page fault, the
|
||||
// kernel will push a fault record onto the exception stack, then branch to
|
||||
@@ -436,6 +469,9 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
|
||||
return sys_ipc_recv( (void *) a1);
|
||||
case SYS_ipc_try_send:
|
||||
return sys_ipc_try_send((envid_t) a1, (uint32_t) a2, (void *) a3, (int) a4);
|
||||
|
||||
case SYS_env_set_trapframe:
|
||||
return sys_env_set_trapframe((envid_t) a1, (struct Trapframe *) a2);
|
||||
case NSYSCALLS:
|
||||
return -E_INVAL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user