Small trouble with paging

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
albeva
Member
Member
Posts: 42
Joined: Thu Aug 21, 2008 8:31 pm

Small trouble with paging

Post by albeva »

Hi

I am new to this forum and OS development in general. I followed an excellent tutorial by Brandon F. From osdever.net I got the sample kernel to compile just fine. But now I am trying to add paging support and got stuck. Could someone point out to me what I am doing wrong?

Code: Select all

#include <system.h>
#include <paging.h>

// the main table
static page_table_t page_table __attribute__ ((aligned (4)));

// the main directory
static page_directory_t page_directory __attribute__ ((aligned (4)));


/**
 * Load the paging
 */
static inline void switch_page_directory(page_directory_t *dir)
{
    //current_directory = dir;
    asm volatile("mov %0, %%cr3":: "r"(dir->physicalAddr));
    uint32 cr0;
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 |= 0x80000000; // Enable paging!
    asm volatile("mov %0, %%cr0":: "r"(cr0));
}


/**
 * Set up the paging
 */
void paging_install ()
{
    // set up pages for first 4MB
    uint32 address = 0;
    int i;
    for (i = 0; i < 1024; i++)
    {
        page_table.pages[i].frame   = address;
        page_table.pages[i].present = 1;
        page_table.pages[i].rw      = 1;
        page_table.pages[i].user    = 1;
        address += 0x1000;
    }

    // set up directory
    page_directory.physicalAddr = (uint32)page_directory.tablesPhysical;
    page_directory.tablesPhysical[0] = (((uint32)&page_table) << 12) | 0x7;

    for(i=1; i<1024; i++)
    {
         page_directory.tablesPhysical[i] = 0;
    };

    switch_page_directory(&page_directory);
}
paging.c

Code: Select all

#ifndef PAGING_H_INCLUDED
#define PAGING_H_INCLUDED

#include <common.h>

/* the page */
typedef struct page
{
    uint32 present    : 1;   // Page present in memory
    uint32 rw         : 1;   // Read-only if clear, readwrite if set
    uint32 user       : 1;   // Supervisor level only if clear
    uint32 accessed   : 1;   // Has the page been accessed since last refresh?
    uint32 dirty      : 1;   // Has the page been written to since last refresh?
    uint32 unused     : 7;   // Amalgamation of unused and reserved bits
    uint32 frame      : 20;  // Frame address (shifted right 12 bits)
} page_t;

/* the table (consists of 1024 entries ) */
typedef struct page_table
{
    page_t pages[1024];
} page_table_t;

/* the directory */
typedef struct page_directory
{
    /**
       Array of pointers to pagetables.
    **/
    //page_table_t * tables[1024];

    /**
       Array of pointers to the pagetables above, but gives their *physical*
       location, for loading into the CR3 register.
    **/
    uint32 tablesPhysical[1024];

    /**
       The physical address of tablesPhysical. This comes into play
       when we get our kernel heap allocated and the directory
       may be in a different location in virtual memory.
    **/
    uint32 physicalAddr;
} page_directory_t;



#endif // PAGING_H_INCLUDED
The rest of teh code is identical to the totorial demo kernel. With only exception calling paging_install() from main

Code: Select all

    gdt_install ();
    idt_install();
    isrs_install();
    irq_install();

    paging_install ();
    init_video();
No matter what I do or try to do it simply crashes. I have a strong feeling I got something very wrong here.

PS! I have looked for inspiration at seakernel sources.
User avatar
cr2
Member
Member
Posts: 162
Joined: Fri Jun 27, 2008 8:05 pm
Location: ND, USA

Re: Small trouble with paging

Post by cr2 »

Can you post the bochs log?

P.S. I just got done with paging yesterday. :wink:
OS-LUX V0.0
Working on...
Memory management: the Pool
User avatar
cr2
Member
Member
Posts: 162
Joined: Fri Jun 27, 2008 8:05 pm
Location: ND, USA

Re: Small trouble with paging

Post by cr2 »

...and why are you commenting out the entires(for the page table) in the page directory? That could be the problem...

P.S. try writing your own code next time, it helps you know what's going on.

*** EDIT: why are you using a #ifndef wrapper in a souce (NOT header) file?
OS-LUX V0.0
Working on...
Memory management: the Pool
User avatar
salil_bhagurkar
Member
Member
Posts: 261
Joined: Mon Feb 19, 2007 10:40 am
Location: India

Re: Small trouble with paging

Post by salil_bhagurkar »

The frame address should be shifted 12 bits as it is the bit field specified. So I guess doing 'address+=0x1000' won't work. You will have to increment the address by only 1 at a time or shift the address by 12 bits and assign it to the frame field.
albeva
Member
Member
Posts: 42
Joined: Thu Aug 21, 2008 8:31 pm

Re: Small trouble with paging

Post by albeva »

I am basically following this http://www.osdever.net/tutorials/paging.php tutorial from bonafide. It didn't work. So I started experimenting. I just took the page_t and page_directory_t from seakernel.
*** EDIT: why are you using a #ifndef wrapper in a souce (NOT header) file?
Huh?
...and why are you commenting out the entires(for the page table) in the page directory? That could be the problem...
The way I understand you got to pass a pointer to the array of page tables (4096 bytes large) so in this case other entries are irrelevent.
P.S. try writing your own code next time, it helps you know what's going on.
I am guilty. However it's a good way to learn by looking what other's have done. I do understand what is going on there. Just don't get it why it crashes.
Can you post the bochs log?
I use VirtualPC. Will try Boch.
albeva
Member
Member
Posts: 42
Joined: Thu Aug 21, 2008 8:31 pm

Re: Small trouble with paging

Post by albeva »

Solved. I think alignment was an issue.
Post Reply