OSDev.org

The Place to Start for Operating System Developers
It is currently Sun Nov 29, 2020 7:26 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: mapping pages > 1 GB, something wrong
PostPosted: Sun Jan 09, 2005 9:22 pm 
Hello!
I've got a problem with my page mapper, but I can't find out what it is, it seems that if I map a page in a page directory entry > 256, it won't get mapped in vmware or on real hardware, but it will in Bochs.

This is my page mapper:
Code:
#define PDE_BASE         0xFFFFF000
#define PTE_BASE         0xFFFFF000
#define PAGE_PO(addr)         ((uint32)(addr) & 0x3FF)
#define PAGE_PTE(addr)         (((uint32)(addr) >> 12) & 0x3FF)
#define PAGE_PDE(addr)         (((uint32)(addr) >> 22) & 0x3FF)

bool MapPage(uint32 *_pdbr, uint32 *_virtual, uint32 *_physical, uint32 *_pdeatt, uint32 *_pteatt)
{
   _virtual = PAGE_ALIGN(_virtual);
   uint32   iPDE = PAGE_PDE(_virtual),
      iPTE = PAGE_PTE(_virtual),
      iPO  = PAGE_PO(_virtual);

   SetPagingEnabled(false);
   uint32 *pPageTable = (uint32 *)((uint32)_pdbr[iPDE] & PDE_BASE);
   if (!pPageTable)
   {
      pPageTable = AllocatePage();
      _pdbr[iPDE] = ((uint32)pPageTable & PDE_BASE) | _pdeatt;
   }

   pPageTable[iPTE] = (((uint32)_physical & PTE_BASE) | _pteatt);
   SetPagingEnabled(bEnabled);

   return true;
}


I pass PAGE_PRESENT|PAGE_WRITE to both _pteatt and _pdeatt.


Top
  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 3:06 am 
Offline
Member
Member

Joined: Wed Oct 18, 2006 11:59 am
Posts: 1600
Location: Vienna/Austria
PTE_BASE should be 0xffc00000

_________________
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image


Top
 Profile  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 4:41 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

I've looked through the code Mr. P posted and couldn't find anything wrong with it.

beyond infinity wrote:
PTE_BASE should be 0xffc00000


Because he's turning paging off before making changes (rather than using the self-reference trick where the physical address of the page directory is used as a page directory entry), PTE_BASE should be 0xFFFFF000...

Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 4:56 am 
Offline
Member
Member

Joined: Wed Oct 18, 2006 11:59 am
Posts: 1600
Location: Vienna/Austria
@brendan:

Thanks for pointing this out. have completely overseen it. Reading is an art, I admit *smirk*

Anyway - with paging turned off, what would happen, if PTE_BASE is in a realm which is not accessible? (no memory present at that location?

I would rather perform this kind of operation with self reference (is immensely handy, I tell ya) and with paging enabled.

1. the virtualization is active - so you can insert any page at "any" location in the page dir /page tables.

2. if something weird is underway, the page fault handler would jump in - even it is trapped inside a double page fault - easier to debug, easier to manage.

_________________
... the osdever formerly known as beyond infinity ...
BlueillusionOS iso image


Top
 Profile  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 7:48 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

beyond infinity wrote:
Thanks for pointing this out. have completely overseen it. Reading is an art, I admit *smirk*


Hehee - I read it the first time, but had some form of bad connection between my eyes and my brain. I read it again so I understood what was going on. Then I read it again, slowly, looking for errors (and didn't find any, so I didn't post). Then you posted a few hours later and I thought I'd messed up, so I read it a few more times to make sure I knew what I was talking about before replying ;D.

beyond infinity wrote:
Anyway - with paging turned off, what would happen, if PTE_BASE is in a realm which is not accessible? (no memory present at that location?


PTE_BASE is being used as a mask (ANDed with the value of a page table entry to remove the attributes), so if it was wrong the physical address of the page table would also be wrong, and it'd all turn to mush in a hurry.

beyond infinity wrote:
I would rather perform this kind of operation with self reference (is immensely handy, I tell ya) and with paging enabled.

1. the virtualization is active - so you can insert any page at "any" location in the page dir /page tables.

2. if something weird is underway, the page fault handler would jump in - even it is trapped inside a double page fault - easier to debug, easier to manage.


A bug will result in similar "symptoms" regardless of which method is used (trashed address space/s).

As I see it the main advantage of self-referencing is that the TLB caches don't have to be entirely flushed (better performance), and it's easier to add support for "global" pages.

The disadvantages are that you have to worry about invalidating the TLB for the area/s you modify (INVLPG), and it's very difficult to debug if you mess this up. It's also harder to wrap your brains around (and therefore easier to write bugs).

Turning paging off and on again allows the kernel to modify any address space (rather than just the one the CPU is using). It also means that the kernel code and stack (and anything else used when paging is disabled) must be identity mapped (linear/virtual address = physical address).


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 8:54 am 
How's that other method working?
Do you point a page directory entry with a fixed index to the page directory base? What good would that make?


Top
  
 
 Post subject: Re:mapping pages > 1 GB, something wrong
PostPosted: Mon Jan 10, 2005 9:33 am 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

Mr. P wrote:
How's that other method working?
Do you point a page directory entry with a fixed index to the page directory base? What good would that make?


I'm surprised this isn't in the Wiki (or prehaps surprised I couldn't find it)..

The general idea is that for each address space you use the physical address of the page directory as a page directory entry.

For example, if you do something roughly equivelent to this (paging turned off):

Code:
   mov eax,cr3
   lea ebx,[eax+1]
   mov [eax+0x00000FFC],ebx


Then after turning paging back on, if you read from 0xFFC00000 the CPU would look at the highest page directory entry trying to find the physical address of the page table to use, and it'll get the page directory's data as if it was a page table. Next the CPU would try to get the page table entry trying to find the physical address of the page to use, which would actually be the first page table. Then the CPU would try to get the actual data to read, which would end up being the first page table entry in the first page table.

Generally you'd end up with an address space that looks like this:

0x00000000 to 0xFFBFFFFF --whatever you like
0xFFC00000 to 0xFFFFEFFF --complete map of all page table entries
0xFFFFF000 to 0xFFFFFFFB -- complete map of all page directory entries
0xFFFFFFFC to 0xFFFFFFFF -- the self-reference

The only real complication (other than it has a tendancy to mess with your head) is invalidating the TLB. Generally it's done as per usual (INVLPG), but if you add or remove a page table you'd need to invalidate the linear address covered by the page table and the corresponding address in the page table mapping (between 0xFFC00000 and 0xFFFFEFFF).

You could avoid this and just flush the entire TLB's by reloading CR3, but...


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 10 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