0

我现在遇到页面错误,这意味着我正在访问无效地址。这很可能是我选择遵循的高半内核设计。但我看不出它在哪里导致页面错误。这是我的 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 all class constructor
//for global objects before
//calling the kernel
typedef void (*constructor)();
extern "C" constructor start_ctors;
extern "C" constructor end_ctors;
extern "C" void callConstructors()
{
    for(constructor* i = &start_ctors; i != &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);
}

好的,您可以看到我注释掉了最后几行.. k_malloc() 是导致所有混乱的原因。出于某种原因,它的 malloc() 低于 0xC0100000 ,这是我们可以为内核设置的最小大小,因为我们使用的是虚拟地址,并且 1MB 是 Grub 相关的东西。说这是我的 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;
}

/*
    Look behind and forward to see if we can merge back into some 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 the block we are located in */
    for (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;
            }

            /* get 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 with it */
                    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);
    for (hb = heap->fblock; hb; hb = hb->next) {
        printf("lcab free looking at 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");
            }
        }
    }
    for (;;);
    /* uhoh.. this should not happen.. */
    return;
}

/*
    This will allocate a chunk of memory by the specified size, and if
    no memory chunk can be found it will 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;


    for (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()
{

}

我认为问题出在 malloc() 上,因为当我将其注释掉时,一切正常。我正在访问该函数中的一些无效地址:

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;


    for (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;
}

. 帮助将不胜感激。这是我在 Github 中的完整源代码:https ://github.com/amanuel2/OS_MIRROR

4

0 回答 0