Jos-lab3 (Exercise 1 & 2)
2014-01-23 15:40
417 查看
Exercise 1.Modify
kern/pmap.cto allocate and map the
inc/memlayout.h) so user processes can read from this array.
You should run your code and make sure
Answer:
// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
// LAB 3: Your code here.
-
+ envs = (struct Env *)boot_alloc(NENV * sizeof(struct Env));
+ memset(pages, 0, NENV * sizeof(struct Env));
//////////////////////////////////////////////////////////////////////
// Now that we've allocated the initial kernel data structures, we set
// up the list of free physicalpages. Once we've done so, all further
@@ -203,7 +204,9 @@ mem_init(void)
// - the new image atUENVS -- kernel R, user R
// -envs itself -- kernel RW, user NONE
// LAB 3: Your code here.
-
+ boot_map_region(kern_pgdir,UENVS,
+ ROUNDUP(NENV*sizeof(struct Env), PGSIZE),
+ PADDR(envs), PTE_U);
Exercise 2.In the file env.c,finish coding the following functions:
123 struct Env *iter = env_free_list;
124 while (i < NENV) {
125 envs[i].env_id = 0;
126 envs[i].env_status = ENV_FREE;
127 i++;
128 iter->env_link =envs + i;
129 }Q:envs在mem_init()里用boot_map_region()已经申请过空间了,就物理空间上应该是紧挨着pages?
199 e->env_pgdir = page2kva(p);
200 memmove(e->env_pgdir,kern_pgdir,PGSIZE);
201 memset(e->env_pgdir,0,PDX(UTOP)*sizeof(pde_t));
原来以为是做映射,其实这边每个enviroment都需要有一个pgdir,让每个用户环境都能映射到4GB的空间。kern_pgdir已经映射到4GB空间,而对于UTOP以上的空间,所有的user enviroment都是和kernel一样的映射,因此可以直接copy过来用。
285 ua = (uint32_t)ROUNDUP(va+len, PGSIZE);
286 la = (uint32_t)ROUNDDOWN(va, PGSIZE);
287 uint32_t size = 0;
288 struct Page *p = NULL;
289 for(size = 0;size < (ua - la);size += PGSIZE) {
290 if (!(p = page_alloc(ALLOC_ZERO)))
291 panic("page allocation failed!\n");
292 // Jacky: Original I thought should use boot_map_region to map, but actually it's only a static mapping, should use page_insert
293 // boot_map_region(e->env_pgdir, va+size, PGSIZE,
294 // page2pa(p), PTE_W|PTE_U);
295 page_insert(e->env_pgdir, p, va+size, PTE_W|PTE_U);
296 }
359 struct Elf *elf = (struct Elf *)binary;
360 struct Proghdr *ph, *eph;
361 if(elf->e_magic != ELF_MAGIC) {
362 cprintf("%s() It's not an ELF file!\n",__func__);
363 return;
364 }
365 // Mistake 1: Almost miss this one, it's changing the address space from k ernel to e enviroment;
366 lcr3((uint32_t)e->env_pgdir);
367 ph = (struct Proghdr *) ((uint8_t *)elf + elf->e_phoff);
368 eph = ph + elf->e_phnum;
369 for (;ph<eph;ph++) {
370 if (ph->p_type != ELF_PROG_LOAD)
371 continue;
372 region_alloc(e,(void *)ph->p_va,ph->p_memsz);
373 memmove((void *)ph->p_va, (uint8_t *)elf + ph->p_offset, ph->p_fil esz);
374 memset((void *)(ph->p_va + ph->p_filesz), 0, ph->p_memsz - ph->p_f ilesz);
375 }
376 // Mistake 2: set the enviroment's entry point
377 e->env_tf.tf_eip = elf->e_entry;
378
379 // Now map one page for the program's initial stack
380 // at virtual address USTACKTOP - PGSIZE.
381
382 // LAB 3: Jacky 140120
383 region_alloc(e, (void *)(USTACKTOP-PGSIZE), PGSIZE);
396 // LAB 3: Jacky140120
397 struct Env* e;
398 int failno = env_alloc(&e, 0);
399 if (failno < 0) {
400 cprintf("%s(0x%x, %d, %d) failed, fail code = %d!\n",__func__, bin ary, size, type);
401 return;
402 }
403 load_icode(*e, binary, size)
404 e->env_type = type;
405 }
522 if(curenv->env_status == ENV_RUNNING)
523 curenv->env_status = ENV_RUNNABLE;
524 }
525 curenv = e;
526 curenv->env_status = ENV_RUNNING;
527 curenv->env_runs++;
528 lcr3(PADDR(curenv->env_pgdir));
529
530 env_pop_tf(&curenv->env_tf);
531 panic("env_run not yet implemented");
As you write these functions,you might find the new cprintf verb
will panic with the message "env_alloc: out of memory".
mem_init()in
kern/pmap.cto allocate and map the
envsarray.This array consists o fexactly
NENVinstances of the
Envstructure allocated much like how you allocated the
pagesarray.Also like the
pagesarray, the memory backing
envsshould also be mapped user read-only at
UENVS(defined in
inc/memlayout.h) so user processes can read from this array.
You should run your code and make sure
check_kern_pgdir()succeeds.
Answer:
// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
// LAB 3: Your code here.
-
+ envs = (struct Env *)boot_alloc(NENV * sizeof(struct Env));
+ memset(pages, 0, NENV * sizeof(struct Env));
//////////////////////////////////////////////////////////////////////
// Now that we've allocated the initial kernel data structures, we set
// up the list of free physicalpages. Once we've done so, all further
@@ -203,7 +204,9 @@ mem_init(void)
// - the new image atUENVS -- kernel R, user R
// -envs itself -- kernel RW, user NONE
// LAB 3: Your code here.
-
+ boot_map_region(kern_pgdir,UENVS,
+ ROUNDUP(NENV*sizeof(struct Env), PGSIZE),
+ PADDR(envs), PTE_U);
Exercise 2.In the file env.c,finish coding the following functions:
env_init()Initialize all of the
Envstructures in the
envsarray and add them to the
env_free_list.Also calls
env_init_percpu, which configures the segmentation hardware with separate segments for privilege level 0 (kernel) and privilege level 3 (user).122 env_free_list =envs;
123 struct Env *iter = env_free_list;
124 while (i < NENV) {
125 envs[i].env_id = 0;
126 envs[i].env_status = ENV_FREE;
127 i++;
128 iter->env_link =envs + i;
129 }Q:envs在mem_init()里用boot_map_region()已经申请过空间了,就物理空间上应该是紧挨着pages?
env_setup_vm()Allocate a page directory for a new environmentand initialize the kernel portionof the new environment's address space.198 p->pp_ref++;
199 e->env_pgdir = page2kva(p);
200 memmove(e->env_pgdir,kern_pgdir,PGSIZE);
201 memset(e->env_pgdir,0,PDX(UTOP)*sizeof(pde_t));
原来以为是做映射,其实这边每个enviroment都需要有一个pgdir,让每个用户环境都能映射到4GB的空间。kern_pgdir已经映射到4GB空间,而对于UTOP以上的空间,所有的user enviroment都是和kernel一样的映射,因此可以直接copy过来用。
region_alloc()Allocates and maps physical memory for an environment284 uint32_t ua,la;
285 ua = (uint32_t)ROUNDUP(va+len, PGSIZE);
286 la = (uint32_t)ROUNDDOWN(va, PGSIZE);
287 uint32_t size = 0;
288 struct Page *p = NULL;
289 for(size = 0;size < (ua - la);size += PGSIZE) {
290 if (!(p = page_alloc(ALLOC_ZERO)))
291 panic("page allocation failed!\n");
292 // Jacky: Original I thought should use boot_map_region to map, but actually it's only a static mapping, should use page_insert
293 // boot_map_region(e->env_pgdir, va+size, PGSIZE,
294 // page2pa(p), PTE_W|PTE_U);
295 page_insert(e->env_pgdir, p, va+size, PTE_W|PTE_U);
296 }
load_icode()You will need to parse an ELF binary image,much like the boot loader already does,and load its contents into the user address spaceof a new environment.358 // LAB 3: Jacky 14020.
359 struct Elf *elf = (struct Elf *)binary;
360 struct Proghdr *ph, *eph;
361 if(elf->e_magic != ELF_MAGIC) {
362 cprintf("%s() It's not an ELF file!\n",__func__);
363 return;
364 }
365 // Mistake 1: Almost miss this one, it's changing the address space from k ernel to e enviroment;
366 lcr3((uint32_t)e->env_pgdir);
367 ph = (struct Proghdr *) ((uint8_t *)elf + elf->e_phoff);
368 eph = ph + elf->e_phnum;
369 for (;ph<eph;ph++) {
370 if (ph->p_type != ELF_PROG_LOAD)
371 continue;
372 region_alloc(e,(void *)ph->p_va,ph->p_memsz);
373 memmove((void *)ph->p_va, (uint8_t *)elf + ph->p_offset, ph->p_fil esz);
374 memset((void *)(ph->p_va + ph->p_filesz), 0, ph->p_memsz - ph->p_f ilesz);
375 }
376 // Mistake 2: set the enviroment's entry point
377 e->env_tf.tf_eip = elf->e_entry;
378
379 // Now map one page for the program's initial stack
380 // at virtual address USTACKTOP - PGSIZE.
381
382 // LAB 3: Jacky 140120
383 region_alloc(e, (void *)(USTACKTOP-PGSIZE), PGSIZE);
env_create()Allocate an environment with
env_allocand call
load_icodeload an ELF binary into it.395 {
396 // LAB 3: Jacky140120
397 struct Env* e;
398 int failno = env_alloc(&e, 0);
399 if (failno < 0) {
400 cprintf("%s(0x%x, %d, %d) failed, fail code = %d!\n",__func__, bin ary, size, type);
401 return;
402 }
403 load_icode(*e, binary, size)
404 e->env_type = type;
405 }
env_run()Start a given environment running in user mode.521 if (curenv) {
522 if(curenv->env_status == ENV_RUNNING)
523 curenv->env_status = ENV_RUNNABLE;
524 }
525 curenv = e;
526 curenv->env_status = ENV_RUNNING;
527 curenv->env_runs++;
528 lcr3(PADDR(curenv->env_pgdir));
529
530 env_pop_tf(&curenv->env_tf);
531 panic("env_run not yet implemented");
As you write these functions,you might find the new cprintf verb
%euseful -- it prints a description corresponding to an error code.For example,
r = -E_NO_MEM; panic("env_alloc: %e", r);
will panic with the message "env_alloc: out of memory".
相关文章推荐
- 使用OS Watcher监控操作系统
- 什么是Mac OS X?跟Linux有什么区别
- DOS命令全集(一)
- DOS下内存的配置
- 基于SQL Server OS的任务调度机制详解
- DOS下的必备工具
- 解析PHP中VC6 X86和VC9 X86的区别及 Non Thread Safe的意思
- DOS 下的批处理文件
- DOS命令全集(二)
- 开源操作系统和必备工具网站收集
- 如果操作系统是一条狗,那 Linux 就是斗牛犬
- Carbyn:第一款基于HTML5的操作系统浮出水面
- 十大史上最恶心的操作系统
- Mac OS X 背后的故事
- Mac OS X 背后的故事(二)——Linus Torvalds的短视
- Mac OS X 背后的故事(三)Mach之父Avie Tevanian
- Mac OS X 背后的故事(四)—— 政客的跨界
- Good OS新版操作系统gOS 3.0桌面图片欣赏