⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paging.cpp

📁 Jazmyn is a 32-bit, protected mode, multitasking OS which runs on i386 & above CPU`s. Its complete
💻 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 + -