Failure when mapping pages

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ellipsis
Posts: 5
Joined: Sat Aug 14, 2010 11:36 am

Failure when mapping pages

Post by ellipsis »

I'm trying to write a paging system, but there's something wrong with my function that maps physical to virtual addresses. I'm trying to map 0x27000 to 0x45000000, but it's mapping it to 0xFFFFFF00.

Here's my page mapping code:

Code: Select all

void paging_mapPage(uint32_t physical, uint32_t virtual, uint32_t flags) {
        // Figure out the PDE and the PTE
        uint32_t directoryAddr = (uint32_t)virtual >> 22;
        uint32_t tableAddr = (uint32_t)virtual >> 12 & 0x03FF;

        // Make sure that a PDE exists
        uint32_t pde = c_pageDir->m_entries[directoryAddr];
        if(pde & PDE_PRESENT) {
                // PDE is present
        } else {
                // Create new PDE
                struct page_table *pt = (struct page_table*)PHYSICAL_TO_VIRTUAL(kpmalloc(sizeof(struct page_table)));
                memset(pt, 0, sizeof(struct page_table));
                c_pageDir->m_entries[directoryAddr] = ((uint32_t)pt & ~0xFFF) | PTE_PRESENT | flags;
                pde = c_pageDir->m_entries[directoryAddr];

                // Wipe the newly allocated page table
                memset((void*)pde, 0, sizeof(struct page_table));
        }

        // Create or modify the PTE
        struct page_table *tbl = (struct page_table*)(pde & ~0xFFF);

        tbl->m_pages[tableAddr] = ((unsigned long)physical) | (flags & 0x0FFF) | 0x01; // Set table entry
        printf("PHYSICAL: 0x%H\n", physical);

        //The TLB must be flushed now
}
The Bochs log is attached.
Any ideas on how to fix this function?
Attachments
bochslog.txt
(11.28 KiB) Downloaded 40 times
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Re: Failure when mapping pages

Post by xyzzy »

Only thing I can see wrong is this:

Code: Select all

                // Wipe the newly allocated page table
                memset((void*)pde, 0, sizeof(struct page_table));
Not only have you already cleared the new page table (the previous memset), the address you're passing is wrong - you use the PDE as an address without clearing flags from it first. Can you post the definitions of the page_table structure and the structure you're using for the page directory?
ellipsis
Posts: 5
Joined: Sat Aug 14, 2010 11:36 am

Re: Failure when mapping pages

Post by ellipsis »

page_table is defined as:

Code: Select all

struct page_table {
         page_tbl_entry m_pages[TBL_PAGES];
} __attribute__((packed, aligned(4096)));
and struct page_directory is defined as:

Code: Select all

struct page_directory {
         page_dir_entry m_entries[DIR_TBLS];
};
ellipsis
Posts: 5
Joined: Sat Aug 14, 2010 11:36 am

Re: Failure when mapping pages

Post by ellipsis »

Could the problem be in the TLB flushing function? It's called right after paging_mapPage().

Code: Select all

void paging_flushTLB(virt_addr addr) {
        __asm__ volatile("cli;invlpg %0;sti;" :: "m" (addr));
}
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Failure when mapping pages

Post by gerryg400 »

Code: Select all

                // Create new PDE
                struct page_table *pt = (struct page_table*)PHYSICAL_TO_VIRTUAL(kpmalloc(sizeof(struct page_table)));
                memset(pt, 0, sizeof(struct page_table));
                c_pageDir->m_entries[directoryAddr] = ((uint32_t)pt & ~0xFFF) | PTE_PRESENT | flags;
Just had a quick look at your code. It looks like pt is a virtual address, but you are storing it in the page directory. The page directory should contain physical addresses.
If a trainstation is where trains stop, what is a workstation ?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Failure when mapping pages

Post by Combuster »

Code: Select all

cli;invlpg %0;sti;
That's a waste of clock cycles - invlpg is atomic as-is, there's absolutely no need to enclose it in an interrupt mutex.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply