예제 #1
0
파일: fork.c 프로젝트: YMChenLiye/os
//拷贝父进程本身所占资源给子进程
static int32_t copy_process(struct task_struct* child_thread,struct task_struct* parent_thread){
	//内核缓冲区,作为父进程用户空间的数据复制到子进程用户空间的中转
	void* buf_page = get_kernel_pages(1);
	if(buf_page == NULL){
		return -1;
	}

	//a 复制父进程的pcb、虚拟地址位图、内核栈到子进程
	if(copy_pcb_vaddrbitmap_stack0(child_thread,parent_thread) == -1){
		return -1;
	}

	//b 为子进程创建页表,此页表仅包括内核空间
	child_thread->pgdir = create_page_dir();
	if(child_thread->pgdir == NULL){
		return -1;
	}


	//c 复制父进程进程体及用户栈给子进程
	copy_body_stack3(child_thread,parent_thread,buf_page);

	//d 构建子进程thread_stack和修改返回值pid
	build_child_stack(child_thread);

	//e 更新文件inode的打开数
	update_inode_open_cnts(child_thread);

	mfree_page(PF_KERNEL,buf_page,1);
	return 0;
}
예제 #2
0
파일: vm.c 프로젝트: jimlar/fusion
void do_fork_vm (process_t   *parent,
		 process_t   *child)
{
  //printf ("FORK_VM: forking memory tables\n");

  // Create a page directory
  if (create_page_dir (child))
  {
    panic ("Cant setup page dir for new child!\n");
  }

  //printf ("FORK_VM: preparing copy on write\n");

  //Setup pagetables
  prepare_copy_on_write (parent, child);

  //printf ("FORK_VM: setting mem-blocks\n");

  //Set the vm_blocks in proc table
  child->vm_code.vm_start = parent->vm_code.vm_start;
  child->vm_code.vm_end = parent->vm_code.vm_end;
  child->vm_code.vm_flags = parent->vm_code.vm_flags;

  child->vm_data.vm_start = parent->vm_data.vm_start;
  child->vm_data.vm_end = parent->vm_data.vm_end;
  child->vm_data.vm_flags = parent->vm_data.vm_flags;

  child->vm_stack.vm_start = parent->vm_stack.vm_start;
  child->vm_stack.vm_end = parent->vm_stack.vm_end;
  child->vm_stack.vm_flags = parent->vm_stack.vm_flags;

  child->vm_kernel_stack.vm_start = parent->vm_kernel_stack.vm_start;
  child->vm_kernel_stack.vm_end = parent->vm_kernel_stack.vm_end;
  child->vm_kernel_stack.vm_flags = parent->vm_kernel_stack.vm_flags;

  //printf ("FORK_VM: done\n");
}
예제 #3
0
파일: vm.c 프로젝트: jimlar/fusion
void vm_setup_init_process (process_t         *init_proc, 
			    Elf32_Phdr        *pht, 
			    int                pht_entries,
			    loaded_module_t   *init_mod)
{
  page_frame_t         *stack_page;
  page_frame_t         *kernel_stack_page;
  int                   i;
  unsigned int          data_min = 0xffffffff;
  unsigned int          data_max = 0;
  unsigned int          code_min = 0xffffffff;
  unsigned int          code_max = 0;
  

  //
  // Create a page directory
  //
  if (create_page_dir (init_proc))
  {
    panic ("Cant setup page dir for init task!\n");
  }

  //
  // HAS TO CHECK PHT AND MAP ACCORDINGLY!!
  //

  //Get page table and insert loaded pages into it
  for (i = 0; i < pht_entries; i++)
  {
    if (pht[i].p_flags & PF_X)
    {
      //It's a code entry
      if (pht[i].p_memsz > PAGE_SIZE)
	panic ("INIT bigger tham one page, not implemented yet!");
      
      if (pht[i].p_memsz > 0)
      {
	code_max = MAX(code_max,(pht[i].p_vaddr + pht[i].p_memsz));
	code_min = MIN(code_min,pht[i].p_vaddr);

	map_page (init_proc, 
		  init_mod->page_frames->page_frame_nr * PAGE_SIZE, 
		  pht[i].p_vaddr, 
		  PAGE_PRESENT | PAGE_USER);
      }

    } else
    {
      //It's a data entry
      if (pht[i].p_memsz > PAGE_SIZE)
	panic ("INIT bigger tham one page, not implemented yet!");
      
      if (pht[i].p_memsz > 0)
      {
	data_max = MAX(data_max,(pht[i].p_vaddr + pht[i].p_memsz));
	data_min = MIN(data_min,pht[i].p_vaddr);

	map_page (init_proc, 
		  init_mod->page_frames->page_frame_nr * PAGE_SIZE, 
		  pht[i].p_vaddr, 
		  PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER);
      }
    }
  }

  //Set the areas in proc table
  init_proc->vm_code.vm_start = code_min;
  init_proc->vm_code.vm_end = code_max;
  init_proc->vm_code.vm_flags = VM_READONLY | VM_CODE;

  init_proc->vm_data.vm_start = data_min;
  init_proc->vm_data.vm_end = data_max;
  init_proc->vm_data.vm_flags = VM_READWRITE;


  //Setup a new stack page
  stack_page = get_free_page ();
  kernel_stack_page = get_free_page ();

  init_proc->tss.ss0 = DS_SELECTOR;
  init_proc->tss.esp0 = PROC_KERNEL_STACK_TOP;

  init_proc->tss.ss = USER_DS_SELECTOR;
  init_proc->tss.esp = USER_STACK_TOP;

  map_page (init_proc, 
	    kernel_stack_page->page_frame_nr * PAGE_SIZE, 
	    PROC_KERNEL_STACK_TOP, 
	    PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER);

  map_page (init_proc, 
	    stack_page->page_frame_nr * PAGE_SIZE, 
	    USER_STACK_TOP, 
	    PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER);

  //vm addresses are linear
  init_proc->vm_kernel_stack.vm_start = PROC_KERNEL_STACK_TOP & PHYS_PAGE_MASK;
  init_proc->vm_kernel_stack.vm_end = (PROC_KERNEL_STACK_TOP & PHYS_PAGE_MASK) + PAGE_SIZE;
  init_proc->vm_kernel_stack.vm_flags = VM_READWRITE;
 
  init_proc->vm_stack.vm_start = USER_STACK_TOP & PHYS_PAGE_MASK;
  init_proc->vm_stack.vm_end = (USER_STACK_TOP & PHYS_PAGE_MASK) + PAGE_SIZE;
  init_proc->vm_stack.vm_flags = VM_READWRITE;
    

  map_standard_pages (init_proc);
}