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.
page table
- Schol-R-LEA
- Member
- Posts: 1925
- Joined: Fri Oct 27, 2006 9:42 am
- Location: Athens, GA, USA
Re: page table
This is actually explained on the wiki page on Paging, but it may not be clear what it is saying.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?
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: Select all
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
};
The page tables themselves are just arrays of 1024 very similar, 32-bit packed bitfield.
Code: Select all
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;
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: Select all
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
}
Last edited by Schol-R-LEA on Wed Mar 08, 2017 8:27 am, edited 1 time in total.
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.
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.
Re: page table
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)
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
-
- The methods to enable IA-32e Paging.
- 捕获1.PNG (9.3 KiB) Viewed 1612 times
Doing steadfastly, or doing nil.