OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:53 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Self-referencing page-directory
PostPosted: Fri Jul 24, 2015 5:54 am 
Offline

Joined: Tue Jul 14, 2015 9:54 pm
Posts: 17
Hello,

since the usual bitshifting and calculating with magic numbers can get really ugly and confusing like in this example:
Code:
void * get_physaddr(void * virtualaddr)
{
    unsigned long pdindex = (unsigned long)virtualaddr >> 22;
    unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;

    unsigned long * pd = (unsigned long *)0xFFFFF000;
    // Here you need to check whether the PD entry is present.

    unsigned long * pt = ((unsigned long *)0xFFC00000) + (0x400 * pdindex);
    // Here you need to check whether the PT entry is present.

    return (void *)((pt[ptindex] & ~0xFFF) + ((unsigned long)virtualaddr & 0xFFF));
}
i've created a little struct, which helps me with those problems:

Code:
typedef struct {
    union {
        struct {
            uint32_t present        : 1;  // 1
            uint32_t write          : 1;  // 2
            uint32_t user           : 1;  // 3
            uint32_t writethrough   : 1;  // 4
            uint32_t cache_disabled : 1;  // 5
            uint32_t accessed       : 1;  // 6
            uint32_t dirty          : 1;  // 7
            uint32_t ignore0        : 1;  // 8
            uint32_t global         : 1;  // 9
            uint32_t avail          : 3;  // 12
            uint32_t frame          : 20; // 32
        };
        uint32_t val;
    };
} page_table_entry_t;

typedef struct {
    union {
        struct {
            uint32_t present        : 1;  // 1
            uint32_t write          : 1;  // 2
            uint32_t user           : 1;  // 3
            uint32_t writethrough   : 1;  // 4
            uint32_t cache_disabled : 1;  // 5
            uint32_t accessed       : 1;  // 6
            uint32_t ignore0        : 1;  // 7
            uint32_t big_pages      : 1;  // 8
            uint32_t ignore1        : 1;  // 9
            uint32_t avail          : 3;  // 12
            uint32_t frame          : 20; // 32
        };
        uint32_t val;
    };
} page_directory_entry_t;

typedef struct {
    page_table_entry_t page[1024];
} page_table_t;

typedef struct {
    union {
        page_table_t table[1023];
        page_table_entry_t page[1024 * 1023];
    };
    page_directory_entry_t directory[1023];
    uint32_t ignore;
} page_directory_t;


This will only work, if the last entry in the page-directory is mapped to itself!
After a single line of initialisation:
Code:
page_directory_t* CURRENT_DIR = (page_directory_t*)0xFFC00000;


It can be used fairly easy:
Code:
uint32_t virtual = 0xC0000000; //our 'demo' virtual address
uint32_t page_id = virtual / 4096; // or rightshift by 12, this is the 'id' of the page
uint32_t table_id = page_id / 1024; // Or rightshift by 10, the table in which the page is
uint32_t table_offset = page_id%1024; // Or &0x3FF, the offset our page in the table
CURRENT_DIR->directory[table_id].present; //Not doing anything, only showing how to access the directory
CURRENT_DIR->directory[table_id].frame; //and so on

//To access a table:
CURRENT_DIR->table[table_id]->page[table_offset].present;

//or even easier with the full page id
CURRENT_DIR->page[page_id].present;


Might be worth to put it in the wiki, might not.


Top
 Profile  
 
 Post subject: Re: Self-referencing page-directory
PostPosted: Tue Jul 28, 2015 4:45 am 
Offline
Member
Member

Joined: Wed Jan 08, 2014 8:41 am
Posts: 100
Location: Moscow, Russia
Note that bit fields in C are not portable. The standard does not dictate whether they appear in little- or big-endian order. This will probably never be a real issue for this piece of (target-specific) code but still worth mentioning.


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: No registered users and 12 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