Exercise 1.i386_init
identifies the file system environment bypassing the typeENV_TYPE_FS
to your environment creationfunction, env_create
.Modifyenv_create
in env.c,so that it gives the file system environment I/O privilege,but never gives that privilege to any other environment.
在env_create()中加入如下的代码
417 if (type == ENV_TYPE_FS) {
418 e->env_tf.tf_eflags = e->env_tf.tf_eflags | FL_IOPL_3;
419 }
我原本直接write_eflags(),其实这只是改变了当前在kernel下的访问权限,并没有对这个enviroment造成影响。
Exercise 2.Implement the bc_pgfault
functions in fs/bc.c.bc_pgfault
is a page fault handler, just like the oneyour wrote in the previous lab for copy-on-write fork, except thatits job is to load pages in from the disk in response to a pagefault. When writing this, keep in mind that (1) addr
may not be aligned to a block boundary and (2) ide_read
operates in sectors, not blocks.
36 addr = ROUNDDOWN(addr, PGSIZE);
37 if ((r = sys_page_alloc(0, addr, PTE_W|PTE_U|PTE_P))<0)
38 panic("%s, sys_page_alloc error: %e",__func__,r);
39 ide_read(blockno*BLKSECTS,addr,BLKSECTS);
原本用了page_alloc() & page_insert(),可是这是kernel里的API,在用户空间必须透过包装过sys call: sys_page_alloc()来调用。
Exercise 3.spawn
relies on the new syscallsys_env_set_trapframe
to initialize the state of thenewly created environment. Implementsys_env_set_trapframe
. Test your code by running theuser/spawnhello programfrom kern/init.c, which will attempt tospawn /hello from the file system.
145 struct Env *e;
146 int r = envid2env(envid, &e, 1);
147 if (r < 0){
148 cprintf("%s(),%d: return %d!\n",__func__,__LINE__,r);
149 return r;
150 }
152 user_mem_check(e, tf, sizeof(struct Trapframe), PTE_U);
153 e->env_tf = *tf;
154 e->env_tf.tf_cs = GD_UT | 3;
155 e->env_tf.tf_eflags |= FL_IF;
156 return 0;
不过在测试的时候一直出现了open()->ipv_send()->sys_page_map()->envid2env()这个函数的权限检查错误。发现这个函数里限定了只有父子关系的进程才能发生ipc 囧。。。
因此我不得不dirty hack了envid2env()中代码,以便让所有进程都能和fs_fs这个进程进行ipc通讯:
102 if (checkperm && e != curenv && e->env_parent_id != curenv->env_id) {
103 if ((e->env_type != ENV_TYPE_FS) && (curenv->env_type != EN V_TYPE_FS)) { // dirty hack to help fsipc between fs and othe r user env.
104 *env_store = 0;
105 return -E_BAD_ENV;
106 }
107 }