exception - Heap Gives Page Fault -
i getting page fault means accessing invalid address. higher half kernel design chose follow. not see leads page fault. here kernel.c++
#include "types.h" #include "gdt.h" #include "stdio.h" #include "serial.h" #include "mem.h" #include "idt.h" #include "timer.h" #include "isr.h" #include "kbd.h" #include "mouse.h" #include "irq.h" #include "string.h" #include "terminal.h" #include "multiboot.h" #include "pmm.h" #include "heap.h" //call class constructor //for global objects before //calling kernel typedef void (*constructor)(); extern "c" constructor start_ctors; extern "c" constructor end_ctors; extern "c" void callconstructors() { for(constructor* = &start_ctors; != &end_ctors; i++) (*i)(); } extern "c" void kernelmain(uint32_t kernel_virtual_end, uint32_t kernel_physical_end, uint32_t placeholder, uint32_t kernel_physical_start, uint32_t kernel_virtual_start, multiboot_info_t *multiboot_structure,uint32_t magicnumber ) { cls(); printf("******kernel info********\n"); printf("kernel start virtual 0x%x\n" , kernel_virtual_start); printf("kernel start physical 0x%x\n" , kernel_physical_start); printf("kernel end virtual 0x%x\n" , kernel_virtual_end); printf("kernel end physical 0x%x\n" , kernel_physical_end); printf("magic 0x%x\n" , magicnumber); printf("*************************"); // printf("********ram info*********\n"); // // // printf("memory upper : %d \n", multiboot_structure->mem_upper); // printf("memory lower : %d \n", multiboot_structure->mem_lower); // // printf("*************************\n"); gdt gt; idt idt; isr isr; irq irq; serialport sp; isr.install_isrs(); irq.install_irqs(); timer timer; timer.install_timer(); kbd kbd; kbd.install_kbd_driver(); mouse mouse; mouse.install_mouse_driver(); __asm__ __volatile__ ("sti"); phyiscalmemorymanager pmm(multiboot_structure); kheap kheap; char *ptr; heap heap((&kheap)); heap.k_addblock(&kheap, (0x100000+0xc0000000), (0x100000+0xc0000000)); //ptr = (char*)heap.k_malloc(&kheap, 256); //heap.k_free(&kheap, ptr); while(1); err: while(1); }
ok can see commented out last lines.. k_malloc() there causing chaos . reason malloc's() bellow 0xc0100000 , minumum size can go kernel, because using virtual addresses and, 1mb grub related stuff. saying here heap.c++ :
#include "heap.h" int heap::k_addblock(kheaplcab *heap, uintptr_t addr, uint32_t size) { kheapblocklcab *hb; kheaphdrlcab *hdr; hb = (kheapblocklcab*)addr; hb->size = size; hb->used = 0; hb->next = heap->fblock; heap->fblock = hb; hdr = (kheaphdrlcab*)&hb[1]; hdr->flagsize = hb->size - (sizeof(kheapblocklcab) + 32); ++heap->bcnt; hb->lastdsize = 0; hb->lastdhdr = 0; return 1; } /* behind , forward see if can merge chunks. */ void heap::k_free(kheaplcab *heap, void *ptr) { kheaphdrlcab *hdr, *phdr, *nhdr; kheapblocklcab *hb; uint32_t sz; uint8_t fg; hdr = (kheaphdrlcab*)ptr; hdr[-1].flagsize &= ~0x80000000; phdr = 0; /* find block located in */ (hb = heap->fblock; hb; hb = hb->next) { if (((uintptr_t)ptr > (uintptr_t)hb) && ((uintptr_t)ptr < (uintptr_t)hb + hb->size)) { hdr = (kheaphdrlcab*)((uintptr_t)ptr - sizeof(kheaphdrlcab)); hdr->flagsize &= ~0x80000000; hb->used -= hdr->flagsize; if (hdr->prevsize) { phdr = (kheaphdrlcab*)((uintptr_t)&hdr - (sizeof(kheaphdrlcab) + hdr->prevsize)); } else { phdr = 0; } /* next header */ nhdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + hdr->flagsize); if ((uintptr_t)nhdr >= ((uintptr_t)hb + hb->size)) { nhdr = 0; } if (nhdr) { if (!(nhdr->flagsize & 0x80000000)) { /* combine */ hdr->flagsize += sizeof(kheaphdrlcab) + nhdr->flagsize; hb->used -= sizeof(kheaphdrlcab); /* set next header prevsize */ nhdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + hdr->flagsize); nhdr->prevsize = hdr->flagsize; } } if (phdr) { if (!(phdr->flagsize & 0x80000000)) { phdr->flagsize += sizeof(kheaphdrlcab) + hdr->flagsize; hb->used -= sizeof(kheaphdrlcab); hdr = phdr; nhdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + hdr->flagsize); if ((uintptr_t)nhdr < (uintptr_t)hb + sizeof(kheapblocklcab) + hb->size) { nhdr->prevsize = hdr->flagsize; } } } /* optimization */ if (hdr->flagsize > hb->lastdsize) { hb->lastdsize = hdr->flagsize; hb->lastdhdr = hdr; } return; } } printf("uhoh ptr:%p\n", ptr); (hb = heap->fblock; hb; hb = hb->next) { printf("lcab free looking @ block:%p next:%p ptr:%p end:%p\n", hb, hb->next, ptr, (uintptr_t)hb + hb->size); if (((uintptr_t)ptr > (uintptr_t)hb)) { printf("above\n"); if (((uintptr_t)ptr < ((uintptr_t)hb + hb->size))) { printf("found\n"); } } } (;;); /* uhoh.. should not happen.. */ return; } /* allocate chunk of memory specified size, , if no memory chunk can found return zero. */ void* heap::k_malloc(kheaplcab *heap, uint32_t size) { kheapblocklcab *hb; kheaphdrlcab *hdr, *_hdr, *phdr; uint32_t sz; uint8_t fg; uint32_t checks; uint32_t bc; checks = 0; bc =0; (hb = heap->fblock; hb; hb = hb->next) { if ((hb->size - hb->used) >= (size + sizeof(kheaphdrlcab))) { ++bc; hdr = (kheaphdrlcab*)&hb[1]; phdr = 0; while ((uintptr_t)hdr < ((uintptr_t)hb + hb->size)) { ++checks; fg = hdr->flagsize >> 31; sz = hdr->flagsize & 0x7fffffff; if (!fg) { if (sz >= size) { if (sz > (size + sizeof(kheaphdrlcab) + 16)) { _hdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + size); _hdr->flagsize = sz - (size + sizeof(kheaphdrlcab)); _hdr->prevsize = size; hdr->flagsize = 0x80000000 | size; hb->used += sizeof(kheaphdrlcab); } else { hdr->flagsize |= 0x80000000; } hb->used += size; return &hdr[1]; } } phdr = hdr; hdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + sz); } } } return 0; } heap::heap(kheaplcab *heap) { heap->fblock = 0; heap->bcnt = 0; } heap::~heap() { }
the problem malloc() think , because when coment out, works fine. accessing invalid address in function :
void* heap::k_malloc(kheaplcab *heap, uint32_t size) { kheapblocklcab *hb; kheaphdrlcab *hdr, *_hdr, *phdr; uint32_t sz; uint8_t fg; uint32_t checks; uint32_t bc; checks = 0; bc =0; (hb = heap->fblock; hb; hb = hb->next) { if ((hb->size - hb->used) >= (size + sizeof(kheaphdrlcab))) { ++bc; hdr = (kheaphdrlcab*)&hb[1]; phdr = 0; while ((uintptr_t)hdr < ((uintptr_t)hb + hb->size)) { ++checks; fg = hdr->flagsize >> 31; sz = hdr->flagsize & 0x7fffffff; if (!fg) { if (sz >= size) { if (sz > (size + sizeof(kheaphdrlcab) + 16)) { _hdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + size); _hdr->flagsize = sz - (size + sizeof(kheaphdrlcab)); _hdr->prevsize = size; hdr->flagsize = 0x80000000 | size; hb->used += sizeof(kheaphdrlcab); } else { hdr->flagsize |= 0x80000000; } hb->used += size; return &hdr[1]; } } phdr = hdr; hdr = (kheaphdrlcab*)((uintptr_t)&hdr[1] + sz); } } } return 0; }
. appreciated. here full source code in github : https://github.com/amanuel2/os_mirror
Comments
Post a Comment