Page 1 of 1

Paging problem

Posted: Sun Jan 07, 2007 8:22 am
by Otter
Hello,
I thougt my paging works well, but a few hours ago I noticed that my vmm is not able to remap a virtual address to a new physical address when the virtual page has been accessed already.

Example:

Code: Select all

requestPageTable(0x001);
pageTable[0x00400] = 0x0080000 | 7;
/* now I want to map page 0x00400 to another physical page */
pageTable[0x00400] = 0x000B8000 | 7;
*(unsigned int*)0x00400000 = 0x0441;
This works fine.

But if I access page 0x00400 before I remap it to 0x000B8000, it does not work anymore:

Code: Select all

requestPageTable(0x001);
pageTable[0x00400] = 0x0080000 | 7;
*(unsigned int*)0x00400000 = 8;
/* now I want to map page 0x00400 to another physical page */
pageTable[0x00400] = 0x000B8000 | 7;
*(unsigned int*)0x00400000 = 0x0441;
This does not work anymore.

I thought this could be because of caching or something like that, but I dunno what to do.

Posted: Sun Jan 07, 2007 8:49 am
by Ready4Dis
Yes, don't forget to invalidate that page table entry (or the entire page directory) before trying to use it! The easiest way (albeit slow way, but works for beginning) make a function called invalidate page, and pass the memroy address to it (this allows for expansion later), then simply mov eax, cr3; mov cr3, eax; This will reload your entire page directory and ALL page table entries (aka, slow), there is an invalidate page instruction that isn't very complicated, but do that just to check that it fixes your problem. If that fixes it, I recommend filling in that function properly so it only invalidates the CPU's cache of the actual page table entry, rather than the entire page directory & all entires ;).

Posted: Sun Jan 07, 2007 9:58 am
by matthias
Or do this:

Code: Select all


unsigned long virtual_addr_to_invalidate;

__asm__ __volatile__("invlpg %0" : : "m" (virtual_addr_to_invalidate));
To invalidate just one page

Posted: Sun Jan 07, 2007 10:18 am
by Ready4Dis
matthias wrote:Or do this:

Code: Select all


unsigned long virtual_addr_to_invalidate;

__asm__ __volatile__("invlpg %0" : : "m" (virtual_addr_to_invalidate));
To invalidate just one page
Also, keep in mind, invlpg is a 486+ instruction, so if you try running your OS on a 386 it will crash, if you don't plan on 386 support, not an issue ;). Just keep that in mind though if you do plan on supporting a 386 (I don't, so for me it's invlpg all the way, but hey, just some info just incase).

Posted: Sun Jan 07, 2007 11:25 am
by Otter
Ok, thanks, now it works.