Esempio n. 1
0
/**
* temp_phys_page - väliaikainen käyttökelpoinen osoitin fyysiseen sivuun
* @page: virtuaalisivun numero (ei oikea sivunumero vaan tämän funktion asia)
* @phys_page: fyysinen sivu, johon virtuaalinen sivu pannaan osoittamaan, tai 0 poistoa varten
**/
void * temp_phys_page(uint_t page, uint_t phys_page)
{
	static uint32_t used[1 + (TEMP_PAGES_COUNT - 1) / 32];
	uint_t used_n, used_b, skip_check = 1;
	if (page < TEMP_PAGES_COUNT) {
		used_n = page / 32;
		used_b = page % 32;
		page += TEMP_PAGES_START;
	} else if (page == TEMPORARY_PAGE_DIRECTORY || page == TEMPORARY_PAGE_TABLE) {
		used_n = 0;
		used_b = 32;
	} else {
		panic("temp_phys_page abuse!\n");
		return 0;
	}
	void *address = PAGE_TO_ADDR(page);
	if (phys_page == 0) {
		KERNEL_PT_ADDR[page].pagenum = page;
		asm_invlpg(address);
		if (!skip_check) {
			used[used_n] &= ~(1 << used_b);
		}
		return 0;
	}
	if (!skip_check) {
		if (used[used_n] & (1 << used_b)) {
			panic("temp_phys_page IN USE!\n");
			return 0;
		}
		used[used_n] |= (1 << used_b);
	}
	KERNEL_PT_ADDR[page].pagenum = phys_page;
	asm_invlpg(address);
	return address;
}
Esempio n. 2
0
union gdt_entry gdt[32];

struct gdt_ptr gdt_ptr;

struct kernel_tasks kernel_tasks = {
	.tss_for_hw_int = {
		.cs = KERNEL_CS_SEL,
		.eip = (uintptr_t) irq_task,
		.ds = KERNEL_DS_SEL,
		.es = KERNEL_DS_SEL,
		.fs = KERNEL_DS_SEL,
		.gs = KERNEL_DS_SEL,
		.ss = KERNEL_DS_SEL,
		.esp = (uintptr_t) &stack_for_hw_int_task,
		.ebp = (uintptr_t) &stack_for_hw_int_task,
		.cr3 = (uintptr_t) PAGE_TO_ADDR(KERNEL_PAGE_DIRECTORY),
		.eflags = 0x02,
	},
	.tss_for_page_fault = {
		.cs = KERNEL_CS_SEL,
		.eip = (uintptr_t) asm_page_fault_handler,
		.ds = KERNEL_DS_SEL,
		.es = KERNEL_DS_SEL,
		.fs = KERNEL_DS_SEL,
		.gs = KERNEL_DS_SEL,
		.ss = KERNEL_DS_SEL,
		.esp = (uintptr_t) &stack_for_page_fault,
		.ebp = (uintptr_t) &stack_for_page_fault,
		.cr3 = (uintptr_t) PAGE_TO_ADDR(KERNEL_PAGE_DIRECTORY),
		.eflags = 0x02,
	},
Esempio n. 3
0
/**
 * Allocate a memory block.
 *
 * On a memory request, the allocator returns the head of a free-list of the
 * matching size (i.e., smallest block that satisfies the request). If the
 * free-list of the matching block size is empty, then a larger block size will
 * be selected. The selected (large) block is then splitted into two smaller
 * blocks. Among the two blocks, left block will be used for allocation or be
 * further splitted while the right block will be added to the appropriate
 * free-list.
 *
 * @param size size in bytes
 * @return memory block address
 */
void *buddy_alloc(int size)
{
	if(size > (1<<MAX_ORDER))
	{
		printf("Size too big for memory space\n");
		return NULL;
	}

	int newOrder = MIN_ORDER;
	while(size > (1<<newOrder))
	{
		newOrder++;
	}
	// printf("Received request of order: %d\n", newOrder);

	int splits = 0;
	Node* temp = find_order(newOrder);
	while(temp == 0)
	{
		newOrder++;
		temp = find_order(newOrder);
		splits++;
	}
	if(splits == 0)
	{
		temp->free = 0;
		return PAGE_TO_ADDR(temp->pageIndex);
	}
	while(splits > 0)
	{
		// printf("Splitting node of order: %d\n", temp->order);
		Node* tempLeft = init_node(temp, temp->pageIndex);
		int pageRight = ADDR_TO_PAGE(BUDDY_ADDR(PAGE_TO_ADDR((unsigned long)temp->pageIndex), (temp->order-1)));
		Node* tempRight = init_node(temp, pageRight);
		temp->left = tempLeft;
		temp->right = tempRight;
		temp->free = 0;
		temp = temp->left;
		splits--;
	}
	temp->free = 0;
	return PAGE_TO_ADDR(temp->pageIndex);



	/*old code
	int index = MIN_ORDER;
	while(size > (1<<index))
	{
		index++;
	}
	struct list_head head = free_area[index];
	if(!list_empty(&head))
	{
		page_t* page = list_entry(head.next, page_t, list);
		page->order = index;
		return PAGE_TO_ADDR((unsigned long) (g_pages - page));
	}
	else
	{
		int splits = 1;
		index++;
		while(index <= MAX_ORDER && list_empty(&(free_area[index])))
		{
			splits++;
			index++;
		}
		head = free_area[index];
		page_t* page =  list_entry(head.next, page_t, list);
		while(splits > 0)
		{
			page_t buddy = g_pages[ADDR_TO_PAGE(BUDDY_ADDR(PAGE_TO_ADDR((unsigned long) (page - g_pages)), (index-1)))];
			buddy.order = index - 1;
			list_add(&buddy.list, &free_area[index-1]);
			splits--;
			index--;
		}
		page->order = index;
		return PAGE_TO_ADDR((unsigned long) (g_pages - page));
	}*/

	return NULL;
}
Esempio n. 4
0
int handle_user_pagefault(void)
{
    phys_pagedir = active_process->mem.phys_pd;

    cr2 = asm_get_cr2();
    dpage = ADDR_TO_PAGE(cr2);
    doffset = eip - (char*) PAGE_TO_ADDR(dpage);
    dpde = dpage / MEMORY_PE_COUNT;
    dpte = dpage % MEMORY_PE_COUNT;

    eip = (void*) kernel_tasks.tss_for_active_thread.eip;
    cpage = ADDR_TO_PAGE(eip);
    coffset = eip - (char*) PAGE_TO_ADDR(cpage);
    cpde = cpage / MEMORY_PE_COUNT;
    cpte = cpage % MEMORY_PE_COUNT;

    const char *panic_msg;
    uint_t new_location;

    page_entry_t *pd, *pt;

    if (!(pd = temp_page_directory(phys_pagedir))) {
        goto no_pd_got;
    }
    if (!pd[dpde].pagenum) {
        goto no_pt_page;
    }
    if ((dpde >= KMEM_PDE_END) && !pd[dpde].user) {
        printf("User process = %d, thread = %d\n", active_pid, active_tid);
        printf("Trying to access address %p (page %d).\n", asm_get_cr2(), ADDR_TO_PAGE(asm_get_cr2()));
        printf("(!pd[dpde].user)\n");
        panic("Bug in memory handling!");
    }
    if (!pd[dpde].present) {
        new_location = swap_in(phys_pagedir, pd[dpde].pagenum);
        if (!new_location) {
            goto no_pt_page_swapped;
        }
        pd[dpde].pagenum = new_location;
        pd[dpde].present = 1;
    }
    if (!(pt = temp_page_table(pd[dpde].pagenum))) {
        goto no_pt_got;
    }
    if (dpde && dpte && !pt[dpte].pagenum) {
        goto no_cr2_page;
    }
    if (!pt[dpte].user) {
        return user_tries_kernel();
    }
    if (dpde < KMEM_PDE_END) {
        printf("User process = %d, thread = %d\n", active_pid, active_tid);
        printf("Trying to access address %p (page %d).\n", asm_get_cr2(), ADDR_TO_PAGE(asm_get_cr2()));
        printf("(dpde < KMEM_PDE_END) && pt[dpte].user)\n");
        panic("Bug in memory handling!");
        return user_tries_kernel();
    }
    if (!pt[dpte].present) {
        new_location = swap_in(phys_pagedir, pt[dpte].pagenum);
        if (!new_location) {
            goto no_cr2_page_swapped;
        }
        pt[dpte].pagenum = new_location;
        pt[dpte].present = 1;
    }

    return 0; // Ratkaistu. :)

no_pd_got:
    panic_msg = "Page fault: failed getting PD from RAM!";
    goto fail;
no_pt_page:
    panic_msg = "Page fault; page missing from PD!";
    goto fail;
no_pt_page_swapped:
    panic_msg = "Page fault; failed swapping PT to RAM!";
    goto fail;
no_pt_got:
    panic_msg = "Page fault; failed getting PT from RAM!";
    goto fail;
no_cr2_page:
    panic_msg = "Page fault; page missing from PT!";
    goto fail;
no_cr2_page_swapped:
    panic_msg = "Page fault; failed swapping page to RAM!";
    goto fail;

fail:
    printf("Page Fault!\nThread %i, process %i\n", active_tid, active_pid);
    printf("Trying to access address %p (page %d).\n", cr2, dpage);
    printf("%s\n", panic_msg);
    return -1;
}