示例#1
0
void init_paging()
{
	size_t sz;
	uint32_t i;
	uint32_t mem_end_page;

	DPRINTK("paging...\t\t");

	mem_end_page = 0x1000000;
	nframes = mem_end_page / PAGE_SIZ;

	sz = INDEX_FROM_BIT(nframes);
	frames = (uint32_t *)kmalloc(sz);
	memset(frames, 0, sz);

	kernel_directory = (struct page_directory *)
		kmalloc_a(sizeof(struct page_directory));
	memset(kernel_directory, 0, sizeof(struct page_directory));

	// don't do this...
	current_directory = kernel_directory;

	// do this instead...
	kernel_directory->physical_addr = (uint32_t)kernel_directory->tables_physical;

	for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ)
		get_page(i, 1, kernel_directory);

	i = 0;
	while (i < placement_addr + PAGE_SIZ) {
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
		i += PAGE_SIZ;
	}

	for (i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZ)
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);

	// register_interrupt_handler(14, page_fault);

	switch_page_directory(kernel_directory);
	enable_paging();

	kheap = create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, 0, 0);

	current_directory = clone_directory(kernel_directory);
        switch_page_directory(current_directory);

	DPRINTK("done!\n");
}
示例#2
0
void initialize_paging(uint32_t memsize)
{
	nframes = memsize / 4;
	frames = (uint32_t *)kmalloc(INDEX_FROM_BIT(nframes));
	uintptr_t pg;

	assert(frames != NULL);

	memset(frames, 0, INDEX_FROM_BIT(nframes));

	uintptr_t physical;
	kernel_directory = (page_directory_t *)kmalloc_ap(sizeof(page_directory_t), &physical);
	memset(kernel_directory, 0, sizeof(page_directory_t));
	current_directory = kernel_directory;

#if 1
	get_page(0,1,kernel_directory)->present = 0;
	set_frame(0);

	for(uintptr_t i = 0x1000; i < placement_address+0x3000; i += 0x1000)
#else
	for(uintptr_t i = 0x0; i < placement_address+0x3000; i += 0x1000)
#endif
	{
		direct_frame( get_page(i, 1, kernel_directory), 1, 0, i);
	}
	
	kernel_directory->physical_addr = (uintptr_t)kernel_directory->tables_physical;

	uintptr_t heap_start = KERNEL_HEAP_START;

	if(heap_start <= placement_address + 0x3000)
	{
		heap_start = placement_address + 0x100000;
	}
	
	for (uintptr_t i = placement_address + 0x3000; i < heap_start; i += 0x1000)
	{
		alloc_frame(get_page(i, 1, kernel_directory), 1, 0);
	}

	for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000)
	{
		get_page(i, 1, kernel_directory);
	}

	for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000)
	{
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
	}
	
	register_isr_handler(13, general_protection_fault);
	register_isr_handler(14, page_fault);	

	switch_page_directory(kernel_directory);

	kernel_heap = create_heap(heap_start, heap_start + KERNEL_HEAP_INIT, KERNEL_HEAP_END, 0, 0);
	//kernel_heap = create_heap(heap_start, KERNEL_HEAP_END, KERNEL_HEAP_END, 0, 0);
}
示例#3
0
文件: fork.c 项目: stupaq/sos-kernel
uint32_t exec_elf(const char* name) {
	fs_node_t* file = finddir(fs_root, name);
	open(file, 1, 0);

	// disable interrupts
	asm volatile("cli");

	// save directory and create one for new task
	page_directory_t* old_dir = current_directory;
	page_directory_t* new_dir = clone_directory(old_dir);

	// switch to new directory (this is where we set up process)
	switch_page_directory(new_dir);

	// load elf and get entry point
	uint32_t entry = load_elf_binary(file);

	// setup stack
	uint32_t stack = (uint32_t) allocate_stack(THREAD_STACK_SIZE);

	// create scheduling structures
	thread_t* new_thread = create_thread((int(*)(void*)) entry, 0,
			(uint32_t*) stack, THREAD_STACK_SIZE);
	task_t* new_task = create_task(new_thread, new_dir);
	schedule_add_task(new_task);

	// switch back to parents directory
	switch_page_directory(old_dir);

	// close executable image
	close(file);

	// reenable interrupts
	asm volatile("sti");

	// like in fork return child pid
	return new_task->pid;
}
示例#4
0
文件: elf.c 项目: exscape/exscapeOS
int execve(const char *path, char *argv[], char *envp[]) {
	INTERRUPT_LOCK;
	int r = elf_load_int(path, (task_t *)current_task, argv, envp);
	kfree((void *)path);
	// argv and envp are freed in elf_load_int
	argv = envp = NULL;

	if (r == 0) {
		assert(interrupts_enabled() == false);
		current_task->state = TASK_RUNNING;
		destroy_user_page_dir(current_task->old_mm->page_directory);
		vmm_destroy_task_mm(current_task->old_mm);
		current_task->old_mm = NULL;

		current_task->did_execve = true;
		current_task->esp = (uint32)current_task->stack - 84 + 12;
		// Overwrite the task's stack with new, zeroed values for registers etc.

		set_task_stack((task_t *)current_task, NULL, 0, 0);
		assert(current_task->new_entry > 0x100000);
		set_entry_point((task_t *)current_task, current_task->new_entry);

		assert(current_directory == current_task->mm->page_directory);
		//current_task->esp = ((uint32)((uint32)USER_STACK_START - sizeof(registers_t)));

		INTERRUPT_UNLOCK;
		YIELD;
		panic("returned past execve()!");
	}
	else {
		assert(r < 0);

		// execve failed! Let's undo most of the work, and return.
		struct task_mm *new_mm = current_task->mm;
		current_task->mm = current_task->old_mm;
		switch_page_directory(current_task->mm->page_directory);

		destroy_user_page_dir(new_mm->page_directory);
		vmm_destroy_task_mm(new_mm);

		INTERRUPT_UNLOCK;
		return r;
	}

	return 0; // To silence warnings
}
示例#5
0
文件: main.c 项目: coin0/RedMagic
// this is main() function for other processors
static int __main(cpu_state_t * cpu)
{
	// init AP
	init_application_processor();

	// init segmentation
	init_global_descriptor_table(cpu);
	init_interrupt_descriptor_table();

	// enable local interrupt
	local_irq_enable();

	// init paging
	switch_page_directory(k_pdir);

	// init sched
	init_sched();

	return 0xFADEFADE;
}
示例#6
0
int
system(
		char *  path, /* Path to the executable to run */
		int     argc, /* Argument count (ie, /bin/echo hello world = 3) */
		char ** argv  /* Argument strings (including executable path) */
	) {
	char ** argv_ = malloc(sizeof(char *) * (argc + 1));
	for (int j = 0; j < argc; ++j) {
		argv_[j] = malloc((strlen(argv[j]) + 1) * sizeof(char));
		memcpy(argv_[j], argv[j], strlen(argv[j]) + 1);
	}
	argv_[argc] = 0;
	char * env[] = {NULL};
	set_process_environment((process_t*)current_process, clone_directory(current_directory));
	current_directory = current_process->thread.page_directory;
	switch_page_directory(current_directory);
	exec(path,argc,argv_,env);
	debug_print(ERROR, "Failed to execute process!");
	kexit(-1);
	return -1;
}
示例#7
0
文件: vm.c 项目: Fluray/OrzOs
void vma_nopage(vma_t *vma, u32int vaddr)
{
    if (!vma)
        return;

    /*printk("cr2 %p\n", current_task->dir->addr);*/
    /*MAGIC_BREAK();*/
    alloc_frame(get_page(vaddr, 1, current_task->dir), 1, vma->flags & VMA_WRITE);
    switch_page_directory(current_task->dir);

    if (vma->flags & VMA_ANON) {
        if (vma->flags & VMA_STACK) {
            vma->vm->end_stack -= 0x1000;
            vma->start -= 0x1000;
        }
        return;
    }

    if (vma->flags & VMA_FILE) {
        file_mapping_t *f_map = (file_mapping_t*)vma->priv;
        u32int size = 0x1000;

        u32int off = vaddr - vma->start;
        if (off >= f_map->size) {
            memset((void*)vaddr, 0, size);
        } else {
            file_lseek(f_map->file, f_map->offset + off, SEEK_SET);
            if (off + size > f_map->size) {
                /*printk("file_read: %p, size: %d\n", vaddr, f_map->size - off);*/
                /*printk("memset: %p, size: %d\n", vma->start+f_map->size, size + off - f_map->size);*/
                file_read(f_map->file, (u8int*)vaddr, f_map->size - off);
                memset((void*)(vma->start + f_map->size), 0, size + off - f_map->size);
            } else {
                /*printk("file_read: %p, size: %d\n", vaddr, size);*/
                file_read(f_map->file, (u8int*)vaddr, size);
            }
        }
    }

}
示例#8
0
文件: elf.c 项目: exscape/exscapeOS
static int elf_load_int(const char *path, task_t *task, char *argv[], char *envp[]) {
	// Loads to a fixed address of 0x10000000 for now; not a HUGE deal
	// since each (user mode) task has its own address space

	assert(interrupts_enabled() == false); // TODO: get rid of the race condition from create_task, so that this isn't needed

	assert(task != NULL);
	struct task_mm *mm = task->mm;
	assert(mm != NULL);

	struct stat st;

	int r;
	if ((r = stat(path, &st)) != 0) {
		assert(r < 0);
		return r;
	}

	uint32 file_size = st.st_size;
	unsigned char *data = kmalloc(file_size);
	int retval = 0;

	int fd = open(path, O_RDONLY);
	if (fd < 0) {
		printk("elf_load(): unable to open %s\n", path);
		retval = fd;
		goto err;
	}

	if ((r = read(fd, data, file_size)) != (int)file_size) {
		printk("elf_load(): unable to read from %s; got %d bytes, requested %d\n", path, r, (int)file_size);
		if (r < 0) {
			retval = r;
			goto err;
		}
		else {
			panic("read() returned less than the expected file size, but not a negative value... why?");
			retval = -EIO;
			goto err;
		}
	}

	close(fd);

	elf_header_t *header = (elf_header_t *)data;

	const unsigned char ELF_IDENT[] = {0x7f, 'E', 'L', 'F'};

	if (memcmp(header->e_ident.ei_mag, &ELF_IDENT, 4) != 0) {
		printk("Warning: file %s is not an ELF file; aborting execution\n", path);
		retval = -ENOEXEC;
		goto err;
	}

	// TODO SECURITY: don't trust anything from the file - users can EASILY execute
	// "forged" ELF files!

	if (header->e_ident.ei_class != ELFCLASS32 || header->e_ident.ei_data != ELFDATA2LSB || \
		header->e_ident.ei_version != 1 || header->e_machine != EM_386 || header->e_type != ET_EXEC) {
		printk("Warning: file %s is not a valid ELF file (invalid ELFCLASS, ELFDATA, version, machine or not ET_EXEC\n");
		retval = -ENOEXEC;
		goto err;
	}

	assert(header->e_entry >= 0x10000000);
	assert(header->e_entry <  0x11000000);

	if (task == current_task) {
		// execve
		assert(current_task->mm != NULL);
		assert(current_task->mm->areas != NULL);
		assert(current_task->mm->page_directory != NULL);
	}

	for (int i=0; i < header->e_phnum; i++) {
		Elf32_Phdr *phdr = (Elf32_Phdr *)(data + header->e_phoff + header->e_phentsize * i);
		if (phdr->p_type == PT_LOAD) {
			// This is a segment to load!

			// Should this be writable to the task?
			bool writable = ((phdr->p_flags & PF_W) ? true : false);

#if ELF_DEBUG
			printk("Segment #%u: copy %u bytes from 0x%08x (data + offset) to 0x%08x (virt in task page dir); read%s\n",
					i, phdr->p_filesz, data + phdr->p_offset, phdr->p_vaddr, writable ? "-write" : "only");
#endif

			if (i == 0)
				assert(phdr->p_vaddr == 0x10000000);
			else
				assert(phdr->p_vaddr > 0x10000000);

			uint32 start_addr = phdr->p_vaddr;
			uint32 start_addr_aligned = (phdr->p_vaddr & 0xfffff000);
			uint32 end_addr   = start_addr + phdr->p_memsz;
			if (!IS_PAGE_ALIGNED(end_addr)) {
				end_addr &= ~(PAGE_SIZE - 1);
				end_addr += PAGE_SIZE;
			}

			if (end_addr > task->mm->brk_start) {
				uint32 new_brk = end_addr;
				if (!IS_PAGE_ALIGNED(new_brk)) {
					new_brk &= ~(PAGE_SIZE - 1);
					new_brk += PAGE_SIZE;
				}
				task->mm->brk_start = new_brk;
				task->mm->brk = new_brk;
			}

			// Allocate memory for this address in the task's address space, set for user mode
			vmm_alloc_user(start_addr_aligned, end_addr, mm, writable);

			// Switch to the new page directory, so that we can copy the data there
			page_directory_t *old_dir = current_directory;
			switch_page_directory(mm->page_directory);

			// Okay, we should have the memory. Let's clear it (since PARTS may be left empty by the memcpy,
			// e.g. the .bss section, and we do want zeroes to be there)
			memset((void *)start_addr_aligned, 0, end_addr - start_addr_aligned);

			// Copy the segment (e.g. .text + .rodata + .eh_frame, or .data + .bss) to the location
			// DO NOT use start_addr_aligned here - we want the program to dictate the exact location

			memcpy((void *)start_addr, data + phdr->p_offset, phdr->p_filesz);

			switch_page_directory(old_dir);
		}
		else if (phdr->p_type == PT_GNU_STACK || phdr->p_type == PT_GNU_RELRO || phdr->p_type == PT_GNU_EH_FRAME) {
			// Quietly ignore
		}
		else
			printk("Warning: skipping unsupported ELF program header (#%u, p_type = 0x%x)\n", i, phdr->p_type);
	}

	// Set up the reentrancy structure for Newlib
	// (It is initialized below, after switching to the new page directory.)
	uint32 reent_size = sizeof(struct _reent);
	if (reent_size & 0xfff) {
		reent_size &= 0xfffff000;
		reent_size += PAGE_SIZE;
	}

	vmm_alloc_user(task->mm->brk, task->mm->brk + reent_size, mm, PAGE_RW);

	//assert(current_directory == kernel_directory);
	page_directory_t *old_dir = current_directory;
	switch_page_directory(task->mm->page_directory);

	task->reent = (struct _reent *)task->mm->brk;
	_REENT_INIT_PTR(task->reent);
	task->mm->brk += reent_size;
	task->mm->brk_start += reent_size;

	assert(IS_PAGE_ALIGNED(task->mm->brk));
	assert(task->mm->brk == task->mm->brk_start);

	// The value brk has when the process starts;
	// userspace may not decrease the brk point below this address
	task->mm->initial_brk = task->mm->brk_start;

	// Copy the argv data from the kernel heap to the task's address space
	// This function updates argv to point to the new location.
	uint32 argc = 0;
	for (; argv[argc] != NULL; argc++) { }
	copy_argv_env_to_task(&argv, argc, task);

	uint32 envc = 0;
	assert(envp != NULL);
	for (; envp[envc] != NULL; envc++) { }
	copy_argv_env_to_task(&envp, envc, task);

	*((uint32 *)(USER_STACK_START - 0)) = (uint32)envp;
	*((uint32 *)(USER_STACK_START - 4)) = (uint32)argv;
	*((uint32 *)(USER_STACK_START - 8)) = (uint32)argc;

	// Update the task's name
	strlcpy((char *)task->name, argv[0], TASK_NAME_LEN);

	if (old_dir != kernel_directory) {
		// execve, stay with the new dir
	}
	else
		switch_page_directory(old_dir);

#if ELF_DEBUG

	printk("File has %u program headers (each %u bytes), %u section headers (each %u bytes)\n",
		   header->e_phnum, header->e_phentsize, header->e_shnum, header->e_shentsize);

	printk("Program Header:\n");
	for (int i=0; i < header->e_phnum; i++) {
		Elf32_Phdr *phdr = (Elf32_Phdr *)(data + header->e_phoff + header->e_phentsize * i);

		if (phdr->p_type == PT_LOAD) {
			printk("LOAD  offset 0x%08x vaddr 0x%08x alignment %u bytes\n", phdr->p_offset, phdr->p_vaddr, phdr->p_align);
			unsigned int f = phdr->p_flags;
			printk("      filesz 0x%08x memsz 0x%08x flags %c%c%c\n", phdr->p_filesz, phdr->p_memsz, 
					(f & PF_R ? 'r' : '-'), (f & PF_W ? 'w' : '-'), (f & PF_X ? 'x' : '-'));
		}
		else {
			printk("unsupported program header (#%u), skipping\n", i);
		}
	}

	// Find the string table
	assert(header->e_shoff != 0); // we need a section header
	Elf32_Shdr *string_table_hdr = (Elf32_Shdr *)(data + header->e_shoff + header->e_shentsize * header->e_shstrndx);
	char *string_table = (char *)(data + string_table_hdr->sh_offset);

	printk("Sections:\n");
	printk("Idx         Name Size     VMA      LMA      File off Align\n");
	for (int i=1; i < header->e_shnum; i++) { // skip #0, which is always empty
		Elf32_Shdr *shdr = (Elf32_Shdr *)(data + header->e_shoff + header->e_shentsize * i);

		char *name = (char *)&string_table[shdr->sh_name];

		printk("%03d %12s %08x %08x %08x %08x %u\n", i, name, shdr->sh_size, shdr->sh_addr, shdr->sh_addr /* TODO: LMA */, shdr->sh_offset, shdr->sh_addralign);
		unsigned int f = shdr->sh_flags;
		printk("                 ");
		if (shdr->sh_type != SHT_NOBITS)
			printk("CONTENTS, ");
		if ((f & SHF_ALLOC))
			printk("ALLOC, ");
		if ((f & SHF_WRITE) == 0)
			printk("READONLY, ");
		if ((f & SHF_EXECINSTR))
			printk("CODE\n");
		else
			printk("DATA\n");
	}
#endif // ELF_DEBUG

	// Try to find symbols, so we can get nice backtrace displays
	Elf32_Sym *symhdr = NULL;
	uint32 num_syms = 0;
	const char *sym_string_table = NULL;
	uint32 string_table_size = 0;

	for (uint32 i=1; i < header->e_shnum; i++) { // skip #0, which is always empty
		Elf32_Shdr *shdr = (Elf32_Shdr *)((uint32)data + header->e_shoff + (header->e_shentsize * i));

		if (shdr->sh_type == SHT_SYMTAB) {
			symhdr = (Elf32_Sym *)(data + shdr->sh_offset);
			num_syms = shdr->sh_size / shdr->sh_entsize;
			Elf32_Shdr *string_table_hdr = (Elf32_Shdr *)((uint32)data + header->e_shoff + shdr->sh_link * header->e_shentsize);
			string_table_size = string_table_hdr->sh_size;
			sym_string_table = (char *)(data + string_table_hdr->sh_offset);
			break;
		}
	}

	// Load symbols for this file, so that we can display them in backtraces
	if (!symhdr || !sym_string_table || num_syms < 1) {
		printk("Warning: failed to load symbols for %s\n", path);
	}
	else {
		// Clone the string table. Because load_symbols doesn't strdup() names
		// for performance reasons, we need the string table to keep existing
		// for as long as the task lives.
		char *old_table = task->symbol_string_table;
		task->symbol_string_table = kmalloc(string_table_size);
		task->symbol_string_table_size = string_table_size;
		memcpy(task->symbol_string_table, sym_string_table, string_table_size);

		if (load_symbols(symhdr, task->symbol_string_table, &task->symbols, num_syms) != 0) {
			printk("Warning: failed to load symbols for %s\n", path);
		}
		else if (old_table) {
			// execve, so free the old one, or it'll leak
			kfree(old_table);
		}
	}

	// If we're still here: set the program entry point
	// (This updates the value on the stack in task.c)
	task->new_entry = (uint32)header->e_entry;
	set_entry_point((task_t *)task, task->new_entry);

	retval = 0;
	/* fall through on success */

err:

	kfree(data);
	assert(retval <= 0);
	return retval;
}
示例#9
0
int free_frame(frame_t * frame)
{
	intmask mask;
	mask = disable();
	//LOG("Freeing");
	//print_frame(frame);
	if(frame->id <5)
	{
		LOG(" WHAT THE F**K %d %d", frame->id, frame->type);
		restore(mask);
		return OK;
	}
	//kprintf("id %d type %d ", frame->id, frame->type);
	//print_fifo_list();
	//kprintf("\n");
	if(frame == NULL)
	{
		restore(mask);
		return SYSERR;
	}
	else if(!FRAMEID_IS_VALID(frame->id))
	{
		restore(mask);
		return SYSERR;
	}
	else if(frame->type == FREE)
	{
		restore(mask);
		return OK;
	}
	else if(frame->type == PAGE){

		//print_fifo_list();
		//LOG("Got here 0.5");
		//3. Using the inverted page table, get vp, the virtual page number of the page to be replaced.
		uint32 vp = frame->vp_no;
		//4. Let a be vp*4096 (the first virtual address on page vp).

		hook_pswap_out(vp, frame->id + FRAME0);
		uint32 a = vp*PAGE_SIZE;

		virtual_addr * virt = (virtual_addr *) &a;

		//5. Let p be the high 10 bits of a. Let q be bits [21:12] of a.
		uint32 p = virt->page_directory_offset;
		uint32 q = virt->page_table_offset;

		//6. Let pid be the process id of the process owning vp.
		pid32 pid = frame->pid;


		//7. Let pd point to the page directory of process pid.
		struct	procent	*prptr;		/* Ptr to process table entry	*/
		prptr = &proctab[pid];
		pd_t * pd = prptr->pagedir;

		if( pd == NULL)
		{
			LOG(" pd doesn't exist ");
			restore(mask);
			return SYSERR;
		}
		bool8 pt_pres = FALSE;
		pt_pres = (bool8) pd[p].pd_pres;

		bool8 pg_pres = FALSE;
		bool8 dirty = FALSE;
		if(pt_pres)
		{	//8. Let pt point to the pid's p_th page table.
			pt_t * pt = (pt_t *) ((pd[p].pd_base) * PAGE_SIZE);
			pg_pres = (bool8) pt[q].pt_pres;
			uint32 pg_base = (uint32) pt[q].pt_base;
			if(pg_pres){
				if((uint32)FRAMEID_TO_VPAGE(frame->id) == pg_base)
				{
					pg_pres = TRUE;
					dirty  = pt[q].pt_dirty;
				}
				else
				{
					pg_pres = FALSE;
				}
			}




		}
		if(pg_pres)
		{
			frame_t * pt_frame = &frames[(pd[p].pd_base) - FRAME0];
			pt_t * pt = (pt_t *) ((pd[p].pd_base) * PAGE_SIZE);
			//9. Mark the appropriate entry of pt as not present.
			pt[q].pt_pres = 0;
			if(pt_frame->type == VPTBL){
				decr_frame_refcount(pt_frame);
				if(pt_frame->refcount == 0){
					pd[p].pd_pres = 0;
					free_frame(pt_frame);

				}


				bzero((char *)&pt[q], sizeof(pt_t));
			}
			else if(pt_frame->type == GPTBL)
			{
			//	kprintf(" Uh  OH");
			}
			// If the reference count has reached zero, you should mark the appropriate entry in pd as "not present."
			// This conserves frames by keeping only page tables which are necessary.
			//LOG("Got here 1.5");

			//If the dirty bit for page vp was set in its page table, you must do the following:
			//a)	Using the backing store map, find the store and page offset within the store, given pid and a.
			//		If the lookup fails, something is wrong. Print an error message and kill the process with id pid.
			//b)	Write the page back to the backing store.

			//LOG("Got here 2");

			if(dirty){
				bsd_t bs_store_id;
				int bs_store_page_offset;
				if(SYSERR == bs_map_check(pid, vp, &bs_store_id, &bs_store_page_offset))
				{
						kprintf("FATAL :Can't find the bs_map");
						restore(mask);
						kill(currpid);
						return SYSERR;
				}
				//print_frame(frame);
				if(BACKSTORE_ID_IS_VALID(frame->backstore) && BACKSTORE_OFFSET_IS_VALID(frame->backstore_offset) && frame->backstore == bs_store_id && frame->backstore_offset == bs_store_page_offset)
				{
					//LOG("Frame %d was dirty", frame->id);
					open_bs(frame->backstore);
					write_bs(FRAMEID_TO_PHYSICALADDR(frame->id), frame->backstore, frame->backstore_offset);
					close_bs(frame->backstore);
				}
				//else
				//{
				//	print_frame(frame);
				//	kprintf("Fatal error: Cannot locate backstore for vpage %d to swap out page for pid %d ", vp, pid);
				//	kill(pid);
				//	initialize_frame(frame);
				//	restore(mask);
				//	return SYSERR;
				//}
			}

			else{
				//print_frame(frame);
			}
		}



		//LOG("Got here 1");
		//10. If the page being removed belongs to the current process,
		// invalidate the TLB entry for the page vp, using the invlpg instruction (see Intel Manual, volumes II and III for more details on this instruction).
		// 11. In the inverted page table, decrement the reference count of the frame occupied by pt.


		//LOG(" Free frame");
		//print_frame(frame);
		enable_paging();
		initialize_frame(frame);
		// Update page table entries associated with this frame
		// set the frame to be free
	}
	else if(frame->type == VPTBL)
	{
		evict_from_fifo_list(frame);
		hook_ptable_delete(frame->id + FRAME0);
		enable_paging();
		initialize_frame(frame);
	}
	else if(frame->type == DIR)
	{
		struct procent * prptrNULL = &proctab[NULLPROC];
		pd_t * null_pg_dir = prptrNULL->pagedir;
		struct	procent	*prptr;		/* Ptr to process table entry	*/
		prptr = &proctab[currpid];
		if(prptr->pagedir!= null_pg_dir)
		{
			evict_from_fifo_list(frame);
			prptr->pagedir = prptrNULL->pagedir;
			switch_page_directory(prptr->pagedir);
			enable_paging();
			initialize_frame(frame);

		}
	}
	restore(mask);
	return OK;

}