/* 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"); }
/*! 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)); } }
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 (); } } }