Hi,
Jeko wrote:Aren't there any other solutions?
There's always more ways... You could leave the page table allocated (good for areas in kernel space that are allocated/freed often), or check if the page table contains all zero (e.g. "repe cmpsd"), or use a mySQL database on the network to keep track, or only allow 4 MiB areas to be allocated and freed, or...
Jeko wrote:I don't know if yours is enough fast, for each page free I must calculate the index of the counter, decrement it and check if it's zero. Isn't it slow?
However how you calculate the index of the counter? (this was my previous question)
Doh - Ego's beat me to it...
Anyway, here's an example of freeing a page (for "plain 32-bit" paging):
Code: Select all
;Input
; ebx Linear address of page to free
free_page:
mov eax,0xFFFFF000 ;eax = mask
and ebx,eax ;Make sure linear address of page to free is aligned
mov esi,ebx ;esi = linear address of page to free
mov edx,ebx ;edx = linear address of page to free
shr esi,22 ;esi = index into page directory mapping
shr edx,12 ;edx = index into page table mapping
test dword [page_directory_mapping + esi * 4],1 ;Is the page table present?
je .error_not_present ; no, can't free a page that isn't present
test dword [page_table_mapping + edx * 4],1 ;Is the page present?
je .error_not_present ; no, can't free a page that isn't present
and eax,[page_table_mapping + edx * 4] ;eax = physical address of page to free
call free_physical_page ;Free the physical page
mov dword [page_table_mapping + edx * 4],0 ;Clear the page table entry
invlpg [ebx] ;Invalidate the page in the TLB
sub [array_of_counters + esi * 2],1 ;Reduce the number of pages using this page table
jne .done ;Skip the rest if the page table is still in use
mov eax,[page_directory_mapping + esi * 4] ;eax = page directory entry
mov dword [page_directory_mapping + esi * 4],0 ;Clear the page directory entry
invlpg [page_table_mapping + edx * 4] ;Invalidate the area in the page table mapping
and eax,0xFFFFF000 ;eax = physical address of page table
call free_physical_page_in_EAX ;Free the physical page that was used for the page table
.done:
ret
Cheers,
Brendan