Page 1 of 1

Small trouble with paging

Posted: Thu Aug 21, 2008 8:40 pm
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.

Re: Small trouble with paging

Posted: Thu Aug 21, 2008 8:42 pm
by cr2
Can you post the bochs log?

P.S. I just got done with paging yesterday. :wink:

Re: Small trouble with paging

Posted: Thu Aug 21, 2008 8:46 pm
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?

Re: Small trouble with paging

Posted: Thu Aug 21, 2008 10:54 pm
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.

Re: Small trouble with paging

Posted: Fri Aug 22, 2008 5:21 am
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.

Re: Small trouble with paging

Posted: Fri Aug 22, 2008 6:57 am
by albeva
Solved. I think alignment was an issue.