Exercise 7.Implement the system calls described abovein kern/syscall.c.You will need to use various functionsin kern/pmap.c and kern/env.c,particularly
envid2env()
.For now, whenever you call
envid2env()
,pass 1 in the
checkperm
parameter.Be sure you check for any invalid system call arguments,returning
-E_INVAL
in that case.Test your JOS kernel with
user/dumbforkand make sure it works before proceeding.
sys_exofork:
89 struct Env *e;
90 int r = env_alloc(&e, curenv->env_id);
91 if (r < 0) {
92 cprintf("%s(),%d: return %d!\n",__func__,__LINE__,r);
93 return r;
94 }
95 e->env_status = ENV_NOT_RUNNABLE;
96 memmove((void *)&e->env_tf,(void *)&curenv->env_tf,sizeof(struct Trapf rame));
97 e->env_tf.tf_regs.reg_eax = 0;
98 return e->env_id;
sys_env_set_status
:
118 struct Env *e = NULL;
119 if ((status != ENV_RUNNABLE) && (status != ENV_NOT_RUNNABLE)) {
120 cprintf("%s(),%d!\n",__func__,__LINE__);
121 return -E_INVAL;
122 }
123 int r = envid2env(envid, &e, 1);
124 if (r < 0){
125 cprintf("%s(),%d: return %d!\n",__func__,__LINE__,r);
126 return r;
127 }
128 e->env_status = status;
129 return 0;
sys_page_alloc
:
174 struct Env *e;
175 if (((uint32_t)va >= UTOP) || ((uint32_t)va % PGSIZE != 0) || ((perm&( ~PTE_SYSCALL)) != 0)){
176 cprintf("%s(),%d!\n",__func__,__LINE__);
177 return -E_INVAL;
178 }
179 int r = envid2env(envid, &e, 1);
180 if (r < 0) {
181 cprintf("%s(),%d: return %d!\n",__func__,__LINE__,r);
182 return r;
183 }
184 struct PageInfo *p = page_alloc(ALLOC_ZERO);
185 if (p == NULL) {
186 cprintf("%s(),%d!\n",__func__,__LINE__);
187 return -E_NO_MEM;
188 }
189 r = page_insert(e->env_pgdir, p, va, perm);
190 if (r < 0) {
191 page_free(p);
192 cprintf("%s(),%d: return %d!\n",__func__,__LINE__,r);
193 return r;
194 }
195 return 0;
sys_page_map
:
226 if (((uint32_t)srcva >= UTOP) || ((uint32_t)srcva % PGSIZE != 0) || (( uint32_t)dstva >= UTOP) || ((uint32_t)dstva % PGSIZE != 0) || ((perm&(~PTE_SYS CALL)) != 0))
227 return -E_INVAL;
228 pte_t *pte;
229 struct Env *srce,*dste;
230 if ((envid2env(srcenvid, &srce, 1) < 0) || (envid2env(dstenvid, &dste, 1) < 0)) {
231 cprintf("%s(),%d: return !\n",__func__,__LINE__);
232 return -E_BAD_ENV;
233 }
234 struct PageInfo *p = page_lookup(srce->env_pgdir, srcva, &pte);
235 if ((p == NULL) || (~(*pte) & perm & PTE_W)) {
236 // cprintf("%s(),%d: (*pte) = 0x%x!\n",__func__,__LINE__, (*pte)) ;
237 return -E_INVAL;
238 }
239 return page_insert(dste->env_pgdir, p, dstva, perm);
sys_page_unmap
:
255 struct Env *env;
256 if (((uint32_t)va >= UTOP) || ((uint32_t)va % PGSIZE != 0)){
257 cprintf("%s(),%d: !\n",__func__,__LINE__);
258 return -E_INVAL;
259 }
260 if (envid2env(envid, &env, 1) < 0){
261 cprintf("%s(),%d: return!\n",__func__,__LINE__);
262 return -E_BAD_ENV;
263 }
264 page_remove(env->env_pgdir, va);
265 return 0;