Пример #1
0
/* Initializes the page allocator. */
void
palloc_init (void) 
{
  /* End of the kernel as recorded by the linker.
     See kernel.lds.S. */
  extern char _end;

  /* Free memory. */
  uint8_t *free_start = pg_round_up (&_end);
  uint8_t *free_end = ptov (ram_pages * PGSIZE);
  size_t free_pages = (free_end - free_start) / PGSIZE;
  size_t user_pages = free_pages / 2;
  size_t kernel_pages;
  if (user_pages > user_page_limit)
    user_pages = user_page_limit;
  kernel_pages = free_pages - user_pages;

  /* Give half of memory to kernel, half to user. */
  init_pool (&kernel_pool, free_start, kernel_pages, "kernel pool");
  init_pool (&user_pool, free_start + kernel_pages * PGSIZE,
             user_pages, "user pool");
}
Пример #2
0
/*! Initializes the swap allocator. */
void swalloc_init(void)
{
    uint32_t i;

    swap_disk = block_get_role(BLOCK_SWAP);
    swap_slots = block_size(swap_disk) / PAGE_SECTORS;

    /* Initialize swap table */
    uint32_t num_pages_used = sizeof(struct swap) * swap_slots;
    num_pages_used = (uint32_t) pg_round_up((void *) num_pages_used) / PGSIZE;

    /* Get pages for swap table */
    swap_list = palloc_get_multiple(PAL_ASSERT | PAL_PAGING | PAL_ZERO, num_pages_used);

    /* Initialize list */
    list_init(open_swap_list);
    /* Initialize swap entries */
    for (i = 0; i < swap_slots; ++i)
    {
        swap_list[i].start_sector = i * PAGE_SECTORS;
        swap_list[i].in_use = false;
        list_push_back(open_swap_list, &(swap_list[i].open_elem));
    }
}
Пример #3
0
static void
syscall_handler (struct intr_frame *f)
{
  int32_t* esp = (int32_t*)f->esp;
  /*
    Any parameters passed to syscall will be above ESP, see illustration below.
    Number of arguments each syscall expects is in argc[] array above.

    syscall number is pointed to by ESP.
    --------------------------------------
    PHYS_BASE
    .................
    <param>
    <param>
    ESP --->    <syscall_number>

    --------------------------------------
  */

  // verify esp pointer is ok, first parameter: current thread
   if(esp == NULL || verify_fix_length(esp, sizeof(esp)) == false){
	sys_exit(-1);
   }

   // esp adress belongs to thread
  if(pagedir_get_page(thread_current()->pagedir, esp) == NULL){
	sys_exit(-1);
   } 

  // ok syscall nr
  int32_t syscall_nr = *esp;
  if(syscall_nr < 0 || syscall_nr >= SYS_NUMBER_OF_CALLS){
	sys_exit(-1);
  }

  // Make sure our data is not overwriting PHYS_BASE.
  int expected_args = argc[syscall_nr];
  unsigned long highest_addr = esp + (expected_args * sizeof(int));
  if(highest_addr >= PHYS_BASE){
	sys_exit(-1);
  }
  
  if(pagedir_get_page(thread_current()->pagedir, highest_addr) == NULL){
	sys_exit(-1);
  }

  /*
  int i = 1;
  for(; i <= expected_args; i++){
	if(verify_fix_length(&esp[i], sizeof(int) ) == false){
		sys_exit(-1);
	}
      
  }
	*/

  DEBUG_SYSCALL("# SYSCALL received = %s\n", get_system_call_name(syscall_nr));
  
  
  switch (syscall_nr)
    {
  
    case SYS_HALT:
      power_off();
      break;
    case SYS_EXEC:
    {

      	f->eax = SYS_EXEC_handler(esp);
    }
    break;
  
    case SYS_WAIT:
    {
      
      int child_pid = *(esp + 1);
      
      f->eax = process_wait (child_pid);
      break; 
    }
  
    case SYS_EXIT:
    {
      if(is_kernel_vaddr(pg_round_up((void*)esp[1]) )){
	sys_exit(-1);
      }
      int exit_status = *(esp + 1);
      process_exit(exit_status);
      thread_exit();
      break;
    }
    case SYS_PLIST:
        process_print_list();
    break;
    case SYS_CREATE:
      {
        bool success = false;

        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
        unsigned initial_size = *(esp + 2);

	if(verify_fix_length(esp[1], initial_size) == false){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}
        success = filesys_create(name, initial_size);

        if(success) {
          DEBUG_SYSCALL("#SYS_CREATE - File with name: %s created. \n", name);

        } else {
          DEBUG_SYSCALL("#SYS_CREATE - filesys_create failed: file named \'%s\' already exists  or internal memory allocation failed \n", name);
        }

        f->eax = success;
        break;
      }
    case SYS_OPEN:
      {
        char *name = (char*)*(esp + 1);
	if(name == NULL){
		sys_exit(-1);
	}
	if(verify_variable_length(esp[1]) == false){
		sys_exit(-1);
	}


        struct file *file;
        file = filesys_open(name);


	int retVal = -1;
        if(file != NULL) {
          DEBUG_SYSCALL("# SYS_OPEN - File with name: '%s' created. \n", name);

	  int fd = flist_add_file(file);
	  retVal = fd;
        } else {
          DEBUG_SYSCALL("# SYS_OPEN - filesys_open failed: no file named \'%s\' exists or internal memory allocation failed \n", name);
          retVal = -1;

        }
	f->eax = retVal;
        break;
      }
    case SYS_READ:
      {
        int retVal = SYS_READ_handler(esp);

        f->eax = retVal;
        break;
      }
    case SYS_CLOSE:
	{
	int retVal = SYS_CLOSE_handler(esp);
	f->eax = retVal;
	
	break;
	}
    case SYS_REMOVE:
	{
		int retVal = SYS_REMOVE_handler(esp);
		f->eax = retVal;
		break;
	}
    case SYS_WRITE:
      {
        int retVal = SYS_WRITE_handler(esp);
        f->eax = retVal;
        break;
      }
    case SYS_SEEK:
	{
	f->eax = SYS_SEEK_handler(esp);
	break;
	}
    case SYS_TELL:

	f->eax = SYS_TELL_handler(esp);
	break;
	

    case SYS_FILESIZE:
	f->eax = SYS_FILESIZE_handler(esp);
	break;
    default:
      {
        DEBUG_SYSCALL ("Executed an unknown system call (nr: %i)!\n", syscall_nr);
        DEBUG_SYSCALL ("Stack top + 0: %d\n", esp[0]);
        DEBUG_SYSCALL ("Stack top + 1: %d\n", esp[1]);

        thread_exit ();
      }
    }
}