OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Mar 18, 2024 11:07 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Problem with activating paging
PostPosted: Sat Jan 14, 2023 3:07 pm 
Offline

Joined: Fri Jan 06, 2023 12:07 pm
Posts: 9
Hello

I am very new to osdev, so please excuse if my problem arises from a complete lack of understanding.
I have read through a few resources and tried implementing paging in C++.

This is the relevant code:
Code:
extern TTY tty;

uint32_t kmalloc_next_address = 0;
void *kmalloc(uint32_t size, bool align)
{
    if (align && (kmalloc_next_address & 0xFFFFF000))
    {
        // Align the address
        kmalloc_next_address &= 0xFFFFF000;
        kmalloc_next_address += 0x1000;
    }
    uint32_t tmp = kmalloc_next_address;
    kmalloc_next_address += size;
    return (void *)tmp;
}


void *kmalloc(uint32_t size)
{
    return kmalloc(size, false);
}

class PageManager {
public:
    PageManager();
    void map_next_free_block_to_page(uint32_t address);
   
private:
    void enable_paging();
    uint32_t* create_new_page_table(uint32_t index);
   
    uint8_t* blocks;
    void set_block(uint32_t address, bool used);

    uint32_t** m_page_directory;
    uint32_t current_page_directory_entry;
};

void PageManager::enable_paging()
{
    // Enable paging
    asm volatile("movl %0, %%cr3" ::"r"((uint32_t)m_page_directory));
    uint32_t cr0;
    asm volatile("movl %%cr0, %0"
                 : "=r"(cr0));
    cr0 |= 0x80000001; // enable paging, by setting bit 31 and bit 1
    asm volatile("movl %0, %%cr0" ::"r"(cr0));
}

PageManager::PageManager()
{
    // Assume we have 4GB of RAM (2^32 bytes), so we need 2^32 / 4096 = 2^21
    uint32_t block_count = 0x100000;
    // Divide by 8 because each byte represents 8 blocks
    blocks = (uint8_t *)kmalloc(block_count / 8);
    // TODO: Replace this with a memset
    for (int i = 0; i < block_count / 8; i++)
    {
        blocks[i] = 0;
    }

    m_page_directory = (uint32_t**)kmalloc(1024 * 4, true);
    for (int i = 0; i < 1024; i++)
    {
        m_page_directory[i] = (uint32_t *)2;
    }
    // Map the first 4MB of memory to the first 4MB of memory
    // This is so we can access the VGA text buffer
    uint32_t *page_table = create_new_page_table(0);
    for (int i = 0; i < 1024; i++)
    {
        page_table[i] = (uint32_t)((i * 0x1000) | 7); // attributes: user level, read/write, present.
        set_block(i * 0x1000, true);
    }
    enable_paging();
    tty.write("Page Manager Initialized");
    tty.write("Enabled Paging!");
}

uint32_t *PageManager::create_new_page_table(uint32_t index)
{
    // TODO: Make sure that the whole page table is mapped
    uint32_t *page_table = (uint32_t *)kmalloc(1024 * 4, true);
    for (int i = 0; i < 1024; i++)
    {
        page_table[i] = 2;
    }
    m_page_directory[index] = (uint32_t *)((uint32_t)page_table | 3);
    return page_table;
}

When I run this code, the VGA text output flickers very weirdly. When I don't enable paging, this doesn't happen and everything works perfectly.
Is there something that I am doing very wrong? I understand that identity mapping the first 4MB of RAM should keep the VGA buffer accesible.

Thank you in advance for the help!


Top
 Profile  
 
 Post subject: Re: Problem with activating paging
PostPosted: Sat Jan 14, 2023 3:29 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5069
Code:
uint32_t kmalloc_next_address = 0;
Code:
    uint32_t tmp = kmalloc_next_address;
Code:
    return (void *)tmp;

Null pointers are undefined behavior.

Have you checked to make sure your memory allocations are happening in memory that you aren't already using for something else?

Have you tried setting a breakpoint on the code that enables paging and stepping through it to see if it starts immediately misbehaving?

Have you tried examining your page tables using a virtual machine? For example, the QEMU monitor offers "info tlb" and "info mem" for describing the page tables.

Have you checked to see if any exceptions are occurring? QEMU (with hardware virtualization disabled) can log exceptions if you add "-d int" to your command line. You should also add "-no-reboot" to make it halt if the CPU triple faults.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], WinExperements and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group