Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
I am confused about paging implementations. It appears as there are two different ways to use paging. Which one is easier to implement. The wiki has a setup for paging which is in this article: Paging
these are the structures that I use that the wiki says to use
typedef struct page
{
u32int present : 1; // Page present in memory
u32int rw : 1; // Read-only if clear, readwrite if set
u32int user : 1; // Supervisor level only if clear
u32int accessed : 1; // Has the page been accessed since last refresh?
u32int dirty : 1; // Has the page been written to since last refresh?
u32int unused : 7; // Amalgamation of unused and reserved bits
u32int frame : 20; // Frame address (shifted right 12 bits)
} page_t;
typedef struct page_table
{
page_t pages[1024];
} page_table_t;
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.
**/
u32int 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.
**/
u32int physicalAddr;
} page_directory_t;
The first gives a definition of page table and page directory entries. The second also defines page table entries, but also includes an unnecessary structure for handling page directories. Using a separate table for the virtual addresses of page tables is unnecessary since one usually maps the entire page directory as a page table.
kfreezen wrote:I'm still confused about them. There are different PTE / PDE layouts all over the web. Which one is easiest or best to use?
There's only one layout of an page directory entry or page table entry - which is how Intel defined it when designing the 386. The One Layout is not defined in code but in documentation, the code you see are various representations of this layout.
If your question was meant to read as "whose code should I rip", the answer must be "write your own so you learn how it works".
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Just create your own structure format following the specifications of the Intel manuals, cannot go wrong with that. James tutorial I believe treats PTEs and PDEs with the same structure as they are only very slightly different in structure.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
The latest version of the Intel Software Developer's Manual refers to three paging modes (Section 4.1.1). Actually, I find their description confusing...
There are three different layouts for the tables (not the modes they are talking about)...
"Normal"/386 mode - looks like the structures above, supports 32 bit virtual and 32 bit physical - easiest to handle and enable.
PSE - basically a hack that gives you 36 bit physical, with 32 bit virtual and short table format - not recommended unless you enjoy pain.
PAE/Long mode - only way to go for 64 bit virtual (can be 36, 48, or 52 bits physical). Entries are double sized (basically another dword on top of these structures, the top bit is NX, bottom bits are the extra physical bits)
Okay, I should have worded it as "I'm confused about different paging structures" because I have found three different PTE structures I have found. 2 of them are in James Molloy's kernel tutorials and one is on this wiki. What I'm confused about is which one is the right one to use.
As Combuster pointed out, there is only one format for a PTE and PDEs; however in James tutorial he combined them in one (which works do to PTEs and PDEs having very similar data structure formats.)
The actual format of the structures were posted in your first post (page_dirent_t, and page_t). However I dont personally recommend using them do to the structure using bit fields. The better method is to redefine the structures to fit your memory management specific implementation needs.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
neon wrote:The better method is to redefine the structures to fit your memory management specific implementation needs.
What? I thought that the CPU requires that the PTE / PDE be exactly as Intel defines it.
The bit structure must match of course. My emphases was on that the OP doesnt need to use any of the above methods; create your own structures or implementation method that best fits your design. Sorry for the confusion.. I could have worded it better
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}