#include "memory.h" #include "console.h" #include "process.h" // ASM linkage void enable_paging(); pd_t *pd = ((pd_t *)(0xFFFFFFFF - (PAGE_SIZE - 1))); //pd_t *kernel_pd; pt_t *pts = ((pt_t *)(0xFFFFFFFF - (1024 * PAGE_SIZE - 1))); pt_t *kernel_pt; size_t memory_size; size_t managed_memory; size_t total_pages; size_t free_pages; char **page_stack_top; char *managed_memory_begin; void *alloc_page() { if (free_pages == 0) { panic(" MEM: Out of memory :(\n"); } void *page = *page_stack_top++; free_pages--; return page; } void free_page(void *page) { *--page_stack_top = page; free_pages++; } void map_page(void *phys_addr, void *virt_addr) { // printf("Virtual addr 0x%x pts base 0x%x\n", virt_addr, pts); unsigned int ipde = ((unsigned int)virt_addr >> 22) & 0x3FF; unsigned int ipte = ((unsigned int)virt_addr >> 12) & 0x3FF; if (!pd[ipde]) { // No page table, create one pt_t *pt = (pt_t *)alloc_page(); memset(pt, 0, 1024 * sizeof(void *)); pd[ipde] = (pt_t *)((size_t)pt | KERNEL_MEMORY_FLAGS); // printf("New PT\n"); } // printf("ipde = %d ipte = %d ... addr = 0x%x\n", ipde, ipte, pts + (ipde * 1024 + ipte)); pts[ipde * 1024 + ipte] = (char *)((size_t)phys_addr | KERNEL_MEMORY_FLAGS); } void *valloc_page() { void *page = alloc_page(); void *addr = (void *)cur_cx->valloc_addr; map_page(page, (void *)cur_cx->valloc_addr); cur_cx->valloc_addr += PAGE_SIZE; return addr; } void *sys_sbrk(unsigned int n) { void *old_top = (void *)cur_cx->heap_top; if (n == 0) { return old_top; } cur_cx->heap_top += n; while (cur_cx->heap_top > cur_cx->valloc_addr) { valloc_page(); } return old_top; } pd_t *create_pd() { pd_t *rpd = (pd_t *)alloc_page(); // FIXME: This will break when we run out of identity mapped memory... rpd[1023] = (pt_t *)((size_t)rpd | KERNEL_MEMORY_FLAGS); rpd[0] = kernel_pt; return rpd; } void memory_init(size_t avail_memory) { kernel_end = (char *)&ld_kernel_end; memory_size = avail_memory; printf(" MEM: Available memory %d bytes\n", memory_size); size_t page_stack_size = ((size_t)memory_size - (size_t)kernel_end) / PAGE_SIZE; page_stack_top = (void *)((size_t)kernel_end + (page_stack_size * sizeof(char *))); // Align at page upper boundary page_stack_top = (void *)(((size_t)(page_stack_top + 0x0FFF) & 0xFFFFF000) - 1); managed_memory_begin = (void *)((size_t)page_stack_top + 1); printf(" MEM: Kernel top 0x%x page stack top 0x%x\n", kernel_end, page_stack_top); managed_memory = memory_size - (size_t)managed_memory_begin; // Make whole pages managed_memory = managed_memory & 0xFFFFF000; printf(" MEM: Managed memory 0x%x\n", managed_memory); printf(" MEM: Managed memory begins at 0x%x\n", managed_memory_begin); char *p; for (p = (char *)(managed_memory_begin + managed_memory); p > managed_memory_begin; p -= PAGE_SIZE) { free_page(p); } printf(" MEM: Free pages: %d\n", free_pages); // printf(" MEM: Physical memory manager initialized. Creating PD\n"); // Initialize kernel identity mapped PT // Map the first 4MB of the memory for kernel // (leave lowest 4kB unmapped for nurupo) kernel_pt = (pt_t *)alloc_page(); pt_t *ptp = kernel_pt + 1; for (p = (char *)4096; p < (char *)(4096 * 1024); p += PAGE_SIZE, ptp++) { *ptp = (char *)((size_t)p | KERNEL_MEMORY_FLAGS); } kernel_pt = (pt_t *)((size_t)kernel_pt | KERNEL_MEMORY_FLAGS); context_init(&kernel_cx); set_cr3(kernel_cx.pd); enable_paging(); // printf(" MEM: Paging is enabled and for some reason it actually seems to work o_O\n"); printf(" MEM: Kernel memory managed initialized.\n"); } // Page fault void interrupt_14(unsigned addr) { printf("Page fault at 0x%x\n", addr); if (addr == 0) { printf("Nurupo... GA!!\n"); } panic("How do I handled Page Fault?"); }