OSDev.org

The Place to Start for Operating System Developers
It is currently Mon May 06, 2024 7:54 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Paging help
PostPosted: Sun Jan 28, 2007 6:38 am 
Offline
Member
Member

Joined: Mon Mar 21, 2005 12:00 am
Posts: 25
Dear thread reader,

I have been searching this forum for two days hoping to find the awnser to my question. I'm working on my kernel and I got GDT IDT ISR and IRQ all setup and working so I'm moving on to my memory manager. My first try at setting up paging worked becouse I worked along with osdever's tutorial. But when I try to change the point at wich the paging starts my kernel crashes, it just reboots (so there is no exception trown?). Here is my paging setup code.

Code:
//Paging.c
//Init paging

//Includes
#include "Kernel.h"

//Functions
extern uint32 asm_getpaging();
extern void   asm_setpaging(uint32 cr0);
extern uint32 asm_getpagaddress();
extern void   asm_setpagaddress(uint32 cr3);

//Vars
uint32* page_directory;
uint32* page_table;
uint8*  page_start;
uint8*  page_usermemory;

//Init paging
void k_initpaging()
{
    //Vars
    uint32 address = 0;
    uint32 i;

    //Set directory and table
    page_directory  = (uint32*)0x200000;
    page_table      = (uint32*)0x210000;
    page_start      = (uint8*)0x100000
    page_usermemory = (uint8*)0x220000;

    //Fill all table entries
    address = (uint32)page_start;
    for (i=0;i<1024;i++)
    {
        page_table[i] = address | 3;
        address += 4096;
    }

    //Setup first page directory
    page_directory[0]  = (uint32)page_table;
    page_directory[0] |= 3;

    //Fill all remaining directory's
    for (i=1;i<1024;i++)
    {
        page_directory[i] = 0|2;
    }

    //Enable paging
    asm_setpagaddress((uint32)page_directory);
    asm_setpaging(asm_getpaging()|0x80000000);
}

//Copyright © 2007 Charlie Gerhardus


Can anybody see why its crashing? And when I got it working what should I do next?

Thanks in advance.

Tjaalie,


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 7:13 am 
Offline
Member
Member

Joined: Sun Dec 31, 2006 11:56 am
Posts: 75
Location: Germany
Quote:
it just reboots (so there is no exception trown?)
No, I'm sure there is an exception thrown, but I guess that either your idt or your exception handler is not available.

If you activate paging, you have to make sure that not only your code is accessible, but also your gdt/idt and of course all isrs, and of course at the same addresses as before you started paging.

If I read your code right, you map the physical space between 0x00100000 and 0x004FFFFF to the virtual space 0x00000000 - 0x003FFFFF ... that means that none of your virtual addresses match the physical addresses. So the system can not find the idt and gdt any more, it can't even find your code because it searches at the same addresses as before you start paging.

[edit]After your paging works you should try to create an address space manager. You have 4 GB of address space ( independant of how much physical memory you have ) and I think you need to decide dynamically how to use it[/edit]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 7:27 am 
Offline
Member
Member

Joined: Mon Mar 21, 2005 12:00 am
Posts: 25
Thanks, so I need to map my kernel to 0x100000 and then it will work again?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 7:37 am 
Offline
Member
Member

Joined: Sun Dec 31, 2006 11:56 am
Posts: 75
Location: Germany
If all your code and kernel data are in this 4 mb, then it should work.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 9:40 am 
Offline
Member
Member

Joined: Mon Mar 21, 2005 12:00 am
Posts: 25
I finaly got it to work but as soon as I use page_count in the loop and not 1024 it goes back to the same old rebooting stuff. Here is the new code

Code:
//Paging.c
//Init paging

//Includes
#include "Kernel.h"

//A page directory
typedef struct
{
    uint32 Offset;
    bool   Free;
    bool   Chain;
} __attribute__((packed)) page_directory;

//Functions
extern uint32 asm_getpaging();
extern void   asm_setpaging(uint32 cr0);
extern uint32 asm_getpagaddress();
extern void   asm_setpagaddress(uint32 cr3);
bool          page_chain(uint32 offset, uint32 count);

//Vars
page_directory* page_directories;
uint32* page_table;
uint32  page_usermemory;
uint32  page_count;

//Init paging
void k_initpaging()
{
    //Vars
    uint32 address = 0;
    uint32 i;

    //Set vars
    page_directories = (page_directory*)0x200000;
    page_table       = (uint32*)0x300000;
    page_usermemory  = 400;
    page_count       = k_getramsize()/1024/4;

    //Fill all table entries
    for (i=0;i<1024;i++)
    {
        page_table[i] = address | 3;
        address += 4096;
    }

    //Fill all remaining directory's
    for (i=0;i<1024;i++)
    {
        page_directories[i].Offset = (uint32)&page_table[i];
        page_directories[i].Offset = page_directories[i].Offset|3;
        page_directories[i].Free   = true;
        page_directories[i].Chain  = false;
    }

    //Enable paging
    asm_setpagaddress((uint32)page_directories);
    asm_setpaging(asm_getpaging()|0x80000000);
}

//Calculate free pages
uint32 k_freepages()
{
    //Vars
    uint32 i;
    uint32 Free = 0;

    //Loop trough all pages and count free ones
    for (i=page_usermemory;i<page_count-page_usermemory;i++)
    {
        if (page_directories[i].Free)
        {
            Free++;
        }
    }

    //Done
    return Free;
}

//Alloc a page or more then one
void* k_allocpage(uint32 count)
{
    //Vars
    uint32  i;
    uint32  x;
    uint32* Offset;

    //Anything to allocate
    if (count == 0)
    {
        return NULL;
    }

    //Loop and find
    for (i=page_usermemory;i<page_count;i++)
    {
        //Free?
        if (page_directories[i].Free)
        {
            //More then one?
            if (count > 1)
            {
                if (!page_chain(i, count))
                {
                    continue;
                }
            }

            //Alloc them
            page_directories[i].Free  = false;
            page_directories[i].Chain = false;

            //Alloc chain
            for (x=1;x<count;x++)
            {
                page_directories[x+i].Free  = false;
                page_directories[x+i].Chain = true;
            }

            //Done
            Offset = (uint32*)page_directories[i].Offset;
            return (void*)*Offset;
        }
    }

    //Failed
    return NULL;
}

//Free allocated pages
void k_freepage(void* start)
{
    //Vars
    uint32 PageNumber = (uint32)start/4096;
    uint32 ChainLen   = 0;
    uint32 i;

    //Get chain len
    i = PageNumber+1;
    while (page_directories[i].Chain)
    {
        i++;
    }
    ChainLen = i-1;

    //Free them
    for (i=PageNumber;i<PageNumber+ChainLen+1;i++)
    {
        page_directories[i].Free  = true;
        page_directories[i].Chain = false;
    }
}

//Is there a chain?
bool page_chain(uint32 offset, uint32 count)
{
    //Vars
    uint32 i;

    //Check bounds
    if (offset+count > page_count)
    {
        return false;
    }

    //Loop and check
    for (i=0;i<count;i++)
    {
        if (!page_directories[i+offset].Free)
        {
            return false;;
        }
    }

    //Succes
    return true;
}

//Copyright © 2007 Charlie Gerhardus



Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 11:41 am 
Offline
Member
Member

Joined: Mon Mar 21, 2005 12:00 am
Posts: 25
I got allocating and deallocating working but I can't write to the pointer that k_allocpage returns. Anyone has an idea why? When I write the address of the pointer to the screen it seems right.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 28, 2007 1:07 pm 
Offline
Member
Member

Joined: Sun Dec 31, 2006 11:56 am
Posts: 75
Location: Germany
Could you tell me the number of the virtual page k_allocpage uses and which address it returns (in hexadezimal notation) ... the last three digits of the address should be zero


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 30, 2007 8:54 am 
Offline
Member
Member

Joined: Mon Jan 08, 2007 3:19 am
Posts: 30
Location: UK
Tjaalie wrote:
I got allocating and deallocating working but I can't write to the pointer that k_allocpage returns. Anyone has an idea why? When I write the address of the pointer to the screen it seems right.


Maybe I'm reading your code wrong, but it looks to me like you're trying to write into the page table, not an allocated page...?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 30, 2007 9:16 am 
Offline
Member
Member

Joined: Sun Dec 31, 2006 11:56 am
Posts: 75
Location: Germany
Quote:
Code:
//A page directory
typedef struct
{
    uint32 Offset;
    bool   Free;
    bool   Chain;
} __attribute__((packed)) page_directory;
I'm not sure about this construction ... are you sure that's correct ? A page directory entry is a 32 bit number, not a struct, not even a packed struct ... Maybe I got it wrong


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 14 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