OSDev.org

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

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: page table
PostPosted: Sat Mar 04, 2017 9:16 am 
Offline

Joined: Sat Mar 04, 2017 8:55 am
Posts: 1
hi.
i have question that related to page table in linux.
i try to understand that concepts.

how do kernel create initially page table?
kernel executes which steps ? (function1 ---> function2 ---> ........... )
page initilazation is difference between x86 and x64 architecture?

i spended two days but i have nothing and i found this site.

thanks in advance.


Top
 Profile  
 
 Post subject: Re: page table
PostPosted: Sat Mar 04, 2017 12:11 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
xkern wrote:
hi.
i have question that related to page table in linux.
i try to understand that concepts.

how do kernel create initially page table?


This is actually explained on the wiki page on Paging, but it may not be clear what it is saying.

The page directory is a 4-KiB-aligned, 1024-element array of 32-bit packed bitfields - in other words, the page directory is itself a page (sort of). Each array element contains a 4-KiB aligned address (that is to say, the upper 20 bits of the address - the page tables themselves have to be aligned on page boundaries, so the lower 12 bits aren't actually needed, and are used for remaining fields), followed by 4 bits of padding (which may or may not be used at some point in the future), followed by one byte of flags. It sort of looks like this,

Code:
typedef page_directory_entry struct {
    uint32_t present: 1;                 // table is in memory
    uint32_t writable: 1;                // read/write if set, r/o if cleared
    uint32_t user_accessible: 1;     // pages can be used in CPL=3 if set
    uint32_t write_through: 1;       // set for write-through caching, cleared for write-back
    uint32_t cache_disabled: 1;      // set to disable caching entirely
    uint32_t accessed: 1;               // at least one page read or written since last cleared
    uint32_t unused: 1;                  // always set to zero
    uint32_t size: 1;                      // set for 4 MiB pages, clear for 4 KiB pages
    uint32_t global: 1;                   // not used in the directory entries     
    uint32_t future: 4;                   // reserved for future uses
    uint32_t table_address: 20;      // page table physical address, 4-KiB or 4-MiB aligned
};


However, actually using bitfields instead of masks and shifts is Not Recommended for a number of reasons.

The page tables themselves are just arrays of 1024 very similar, 32-bit packed bitfield.

Code:
typedef page_table_entry struct {
    uint32_t present: 1;                 // page is in memory
    uint32_t writable: 1;                // read/write if set, r/o if cleared
    uint32_t user_accessible: 1;     // page can be used in CPL=3 if set
    uint32_t write_through: 1;       // set for write-through caching, cleared for write-back
    uint32_t cache_disabled: 1;      // set to disable caching entirely
    uint32_t accessed: 1;              // page read from since last cleared
    uint32_t dirty: 1;                     // page written to since last cleared
    uint32_t unused: 1;                  // always set to zero
    uint32_t global: 1;                   // no TLB updates when in CPL=3     
    uint32_t future: 4;                   // reserved for future uses
    uint32_t page_address: 20;      // page physical address, 4-KiB or 4-MiB aligned
} PAGE_ENTRY;


The main differences are a) the directory entries describe all the entries in the page table it points to, and take precedence over the page table entries, and b) the dirty and global bits are ignored in the directory entries, while the size bit is ignored in the table entries.

To use the page directory, you first allocate memory space for the page directory and at least one page table (you should clear those arrays to make sure you don't have any garbage entries), then populate the starting page table entries in whatever way you find useful, then set the page directory entries for the page tables.

Once that is done, you copy the address of the page directory to CR3, then set the PE and PG bits in CR0 (bits 0 and 31, respectively). The section on Enabling has code for this.

The wiki page on Identity Paging has a simple example of how to set the page table entries of one table so that they map the first 1MiB of the virtual address space to the 1 MiB of physical memory. For something more general, you would probably use masks of the individual fields and the aligned addresses of the pages you are looking to use (or use bit fields if you trust the compiler to get it right). Just to give you some idea:

Code:
page_directory_entry page_directory[1024];   // for now assume something like this is global in the kernel

page_table_entry* get_page_entry(uint16_t dir_index, uint16_t entry_index)
{
     page_directory_entry table_descriptor;
     page_table_entry* table;

    // first, check to see if the index is a valid 12 bit offset
    if (dir_index >  0x0fff || entry_index > 0x0fff)
    {
        return -1;     // or do something else to indicate an error
    }
    else
    {
        table_descriptor = page_directory[dir_index];
        table = (page_table_entry *) (table_descriptor | 0x0FFF);
        // make sure that the directory entry is for an actual address
        if (table)
        {
            return table + entry_index;
        }
        else
        {
            return -2;  or some other error indication
        }
    }
}   

bool is_dirty(page_table_entry* page_entry)
{
      return (bool) (*page_table_entry | 4);  // extract bit 7
}

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Last edited by Schol-R-LEA on Wed Mar 08, 2017 8:27 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: page table
PostPosted: Wed Mar 08, 2017 7:58 am 
Offline
Member
Member
User avatar

Joined: Sat Dec 31, 2016 1:43 am
Posts: 48
Location: China
I think I can give a example of x64 paging(IA-32e Paging)

For more information, you can download Intel manual and go to chapter 4.(http://www.intel.cn/content/www/cn/zh/p ... nuals.html)


Attachments:
File comment: The whole structure of IA-32e Paging.
捕获2.PNG
捕获2.PNG [ 16.56 KiB | Viewed 1414 times ]
File comment: The methods to enable IA-32e Paging.
捕获1.PNG
捕获1.PNG [ 9.3 KiB | Viewed 1415 times ]

_________________
Doing steadfastly, or doing nil.
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot], Sa41848, SemrushBot [Bot] and 58 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