Hi,
Normally (for plain 32 bit paging), when I create a new page directory I do something like this:
Code: Select all
mov eax,edi ;eax = physical address of page directory
or eax,00000011b ;eax = page directory entry (present and read/write flags set)
mov [edi+0xFFC],eax ;Set page directory into itself
After this, all page directory entries will be mapped from 0xFFFFF000 to 0xFFFFFFFF, and all page table entries will be mapped from 0xFFC00000 to 0xFFFFFFFF.
It works because the page directory becomes the highest page table, and all page tables become pages.
To find the physical address of a page you'd do something like:
Code: Select all
;Input
; esi = linear address of page
convertLinearToPhysical:
mov eax,esi ;eax = linear address
shr eax,21 ;eax = page directory entry number for linear address
test [0xFFFFF000+eax*4],1 ;Is page table present?
je .pageNotPresent ; no, error
mov eax,esi ;eax = linear address
shr eax,12 ;eax = page table entry number for linear address
mov eax,[0xFFC00000+eax*4] ;eax = page table entry
test eax,1 ;Is page present?
je .pageNotPresent ; no, error
and eax,0xFFFFF000 ;eax = physical address of page
ret
To add a page to the address space you'd do something like:
Code: Select all
;Input
; ebx = physical address of page to map
; ecx = access flags for page
; esi = linear address to map page
mapPage:
or ebx,ecx ;ebx = page table entry
mov eax,esi ;eax = linear address
shr eax,21 ;eax = page directory entry number for linear address
test [0xFFFFF000+eax*4],1 ;Is page table present?
jne .hasPT ; yes
call allocatePhysicalPage ; no, allocate a physical page,
or eax,<page_dir_flags> ; and set the access flags,
mov [0xFFFFF000+eax*4],eax ; and put the page table into the page directory
.hasPT:
mov eax,esi ;eax = linear address
shr eax,12 ;eax = page table entry number for linear address
test [0xFFC00000+eax*4],1 ;Is a page already present?
jne .pageNotPresent ; yes, error
mov [0xFFC00000+eax*4],ebx ;Set the new page table entry
ret
Of course this will not work if the same page or page table needs to be mapped into other addresss spaces. For solutions to this problem see
the other discussion.
I've also ignored things like re-entrancy locking, proper error handling and probably other things, but it hopefully gives you a good idea of how this works...
Cheers,
Brendan