?? paging.cpp
字號:
/*
* Copyright (C) 2004, Thejesh AP. All rights reserved.
*/
#include <sys\types.h>
#include <null.h>
#include <stdlib.h>
#include <string.h>
#include <drivers\console.h>
#include <jazmyn\i386.h>
#include <mm\paging.h>
#include <mm\heap.h>
#define __KERNEL_VA (256*1024*1024)
#define _K_HEAP_SZ 0x2000000
paging::paging()
{
page_dir = NULL;
num_tables = 0;
alloc_start = 0;
uint kheap_base = (uint)init_paging((uint*)0x100000);
enable_paging(0x100000);
uint last_pg = (kheap_base + _K_HEAP_SZ) / PAGE_SIZE;
for(int pg=0;pg<last_pg;pg++)
mark_page(pg);
set_alloc_start(last_pg);
extern heap _heap_obj;
_heap_obj.init_heap(kheap_base,_K_HEAP_SZ);
}
paging::~paging()
{
}
uint get_physical_mem()
{
ulong *ptr = (ulong*)0x100000;
ulong temp;
while(1)
{
temp = *ptr;
*ptr = 0xAABBCCDD;
if(*ptr != 0xAABBCCDD)
break;
*ptr = temp;
ptr = ptr + 4096;
}
return (uint)ptr;
}
void* paging::init_paging(uint *dir_base)
{
/*kernel virtual address space == 256 MB*/
cout<<"Initializing paging";
page_dir = dir_base;
uint virt_mem = -1;
uint phys_mem = get_physical_mem();
uint virt_no_of_pages = (virt_mem / PAGE_SIZE)+1;
uint phys_no_of_pages = phys_mem / PAGE_SIZE;
num_tables = (virt_no_of_pages / NUM_PAGE_ENTRIES);
uint *page_table;
ullong page = 0;
int dum = 0;
for(int i=0;i<num_tables;i++)
{
page_table = (uint*)((uint)page_dir+((i+1)*0x1000));
page_dir[i] = (uint)page_table|PRESENT|RD_WR|USR_SUP;
for(int j=0;j<NUM_PAGE_ENTRIES;j++)
{
if(page < phys_mem)
page_table[j] = page|PRESENT|RD_WR|USR_SUP;
else if(page >= phys_mem && page < __KERNEL_VA)
page_table[j] = page|RD_WR;
page = page + 4096;
}
if(i == dum * 64)
{
cout<<'.';
dum++;
}
}
cout<<" [OK]"<<endl;
return (void*)((uint)page_table + PAGE_SIZE);
}
int paging::get_free_pages(int num_pages)
{
uint pte;
int starting_page;
int prev_page = -1;
int curr_page;
int success = 0,saved = 0,cnt = 0;
int spt = GET_TAB_NO(alloc_start);
int spe = GET_ENT_NO(alloc_start);
for(int pt=spt;pt<num_tables;pt++)
for(int entry=spe;entry<NUM_PAGE_ENTRIES;entry++)
{
pte = get_pte(pt,entry);
if(!IS_MARKED(pte))
{
if(!saved)
{
starting_page = GET_PAGE_NUM(pt,entry);
saved = 1;
}
if(prev_page == -1)
{
prev_page = GET_PAGE_NUM(pt,entry);
curr_page = prev_page;
cnt++;
if(cnt < num_pages) continue;
else
{
success = 1;
goto end;
}
}
else
curr_page = GET_PAGE_NUM(pt,entry);
if(curr_page == prev_page + 1)
{
prev_page = curr_page;
cnt++;
if(cnt<num_pages) continue;
else
{
success = 1;
goto end;
}
}
}
else
{
if(saved)
{
saved = 0;
prev_page = -1;
cnt = 0;
}
}
}
end:
if(success) return starting_page;
return -1;
}
void* paging::alloc_pages(int num_pages)
{
int starting_page = get_free_pages(num_pages);
if(starting_page == -1) return NULL;
int pg;
for(pg=starting_page;pg<starting_page+num_pages;pg++)
{
mark_page(pg);
}
mark_last_page(pg-1);
return (void*)(starting_page*PAGE_SIZE);
}
void paging::free_pages(void* addrs)
{
int starting_page = (int)addrs / PAGE_SIZE;
int last = 0;
for(int pg=starting_page;;pg++)
{
uint ptn = GET_TAB_NO(pg);
uint pen = GET_ENT_NO(pg);
uint entry = get_pte(ptn,pen);
if(entry & LAST_PAGE)
{
entry = entry & ~LAST_PAGE;
set_pte(ptn,pen,entry);
last = 1;
}
if(IS_MARKED(entry)) unmark_page(pg);
else
{
cout<<"Invalid address specified\n";
break;
}
if(last) break;
}
}
paging _paging_obj;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -