📄 memory.cpp
字号:
/*
* Copyright (C) 2004, Thejesh AP. All rights reserved.
*/
#include <sys\types.h>
#include <jazmyn\const.h>
#include <null.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <mm\new.h>
#include <jazmyn\i386.h>
#include <jazmyn\desc.h>
#include <jazmyn\gdt.h>
#include <fs\devmgr.h>
#include <fs\fatvol.h>
#include <semaphore.h>
#include <fs\fatdriver.h>
#include <mm\heap.h>
#include <mm\paging.h>
#include <mm\memory.h>
#include <drivers\console.h>
#include <drivers\keyboard.h>
#define _cs_sel (0|7)
#define _ds_sel (8|7)
extern paging _paging_obj;
extern GDT _gdt;
extern FATdriver _FAT_driver;
extern char *environ[];
memory::memory()
{
physical_base = NULL;
_tss_sel = _gdt.set_tss((uint)&tss,sizeof(tss));
_ldt_sel = _gdt.set_ldt((uint)&ldt[0],sizeof(ldt[0])*2);
}
memory::~memory()
{
delete mm.virtual_page;
delete mm.physical_page;
_paging_obj.free_pages(physical_base);
physical_base = NULL;
}
void memory::init_memory(void *buf,uint cs,uint ds,uint bss,uint ss,uint ep)
{
CS = cs;
DS = ds;
BSS = bss;
int db = DS + BSS;
int n = db / PAGE_SIZE;
if(db % PAGE_SIZE) n++;
HEAP = (n*PAGE_SIZE - (DS + BSS)) + PAGE_SIZE;
SS = ss;
int total = CS + DS + BSS + HEAP + SS;
entry_point = ep;
mm.prog_pages = total / PAGE_SIZE;
if(total % PAGE_SIZE) mm.prog_pages++;
mm.virtual_page = new uint[mm.prog_pages];
mm.physical_page = new uint[mm.prog_pages];
if(!mm.virtual_page || !mm.physical_page)
{
cout<<"error allocting mem\n";
}
physical_base = _paging_obj.alloc_pages(mm.prog_pages);
memcpy(physical_base,buf,mm.prog_pages*PAGE_SIZE);
set_cs(ldt[0]);
set_ds(ldt[1]);
set_mem_map();
set_table_entries();
// _heap.init_heap(__VIRTUAL_BASE+CS+DS+BSS,HEAP);
_heap.init_heap((uint)physical_base+CS+DS+BSS,HEAP);
uint stk_top = mm.prog_pages * PAGE_SIZE - 1;
set_tss(0,0,0,0,0,0,0,_ds_sel,_ds_sel,_ds_sel,_ds_sel,
entry_point,_cs_sel,0x202,stk_top,_ds_sel);
}
void memory::set_cs(seg_desc &desc)
{
uint limit = mm.prog_pages * PAGE_SIZE;
desc.lim_low = limit&0xFFFF;
desc.lim_flags = ((limit>>16)&0xF);
desc.lim_flags = desc.lim_flags | D_BIG;
/* desc.base_low = __VIRTUAL_BASE&0xFFFF;
desc.base_mid = (__VIRTUAL_BASE>>16)&0xFF;
desc.base_high = (__VIRTUAL_BASE>>24)&0xFF;*/
desc.base_low = (uint)physical_base&0xFFFF;
desc.base_mid = ((uint)physical_base>>16)&0xFF;
desc.base_high = ((uint)physical_base>>24)&0xFF;
desc.access = D_PRESENT|D_DPL_3|D_DT_APP|D_CODE|D_READ|D_CONFIRMING;
}
void memory::set_ds(seg_desc &desc)
{
uint limit = mm.prog_pages * PAGE_SIZE;
desc.lim_low = limit&0xFFFF;
desc.lim_flags = ((limit>>16)&0xF);
desc.lim_flags = desc.lim_flags|D_BIG;
/* desc.base_low = __VIRTUAL_BASE&0xFFFF;
desc.base_mid = (__VIRTUAL_BASE>>16)&0xFF;
desc.base_high = (__VIRTUAL_BASE>>24)&0xFF;*/
desc.base_low = (uint)physical_base&0xFFFF;
desc.base_mid = ((uint)physical_base>>16)&0xFF;
desc.base_high = ((uint)physical_base>>24)&0xFF;
desc.access = D_PRESENT|D_DPL_3|D_DT_APP|D_DATA|D_WRITE;
}
void memory::set_mem_map()
{
int virtual_page = __VIRTUAL_BASE / PAGE_SIZE;
int physical_page = (uint)physical_base / PAGE_SIZE;
for(int i=0;i<mm.prog_pages;i++)
{
mm.virtual_page[i] = virtual_page;
mm.physical_page[i] = physical_page;
virtual_page++;
physical_page++;
}
}
void memory::set_table_entries()
{
for(int i=0;i<mm.prog_pages;i++)
{
int ptn = GET_TAB_NO(mm.virtual_page[i]);
int pen = GET_ENT_NO(mm.virtual_page[i]);
uint entry = (mm.physical_page[i]*PAGE_SIZE)|PRESENT|RD_WR|USR_SUP;
_paging_obj.set_pte(ptn,pen,entry);
}
}
void memory::set_tss(uint eax,uint ebx,uint ecx,uint edx,uint esi,uint edi,uint ebp,uint gs,
uint fs,uint es,uint ds,uint eip,uint cs,uint eflags,uint esp,uint ss)
{
tss.esp0 = (ulong)&kernel_stack[8191];
tss.ss0 = KERNEL_SS_SEL;
tss.cr3 = _CR3;
tss.eip = eip;
tss.eflag = eflags;
tss.esp = esp;
tss.ebp = ebp;
tss.edi = edi;
tss.esi = esi;
tss.edx = edx;
tss.ecx = ecx;
tss.ebx = ebx;
tss.eax = eax;
tss.cs = cs;
tss.ds = ds;
tss.ss = ss;
tss.es = es;
tss.fs = fs;
tss.gs = gs;
tss.ldt = _ldt_sel;
tss.trap = 0;
tss.io_map_base = 0xFFFF;
tss.end = 0xFF000000;
}
memory& memory::operator=(memory &parent)
{
mm.prog_pages = parent.mm.prog_pages;
mm.virtual_page = new uint[mm.prog_pages];
mm.physical_page = new uint[mm.prog_pages];
physical_base = _paging_obj.alloc_pages(mm.prog_pages);
if(!mm.virtual_page || !mm.physical_page)
{
cout<<"Error allocating mem\n";
getch();
}
set_mem_map();
set_cs(ldt[0]);
set_ds(ldt[1]);
CS = parent.CS;
DS = parent.DS;
BSS = parent.BSS;
HEAP = parent.HEAP;
SS = parent.SS;
memcpy(physical_base,parent.physical_base,mm.prog_pages*PAGE_SIZE);
_heap = parent._heap;
return *this;
}
int memory::try_to_replace(int fd,int argc,char **argv,char **env,uint cs,uint ds,uint bss,
uint ss,uint ep)
{
char **targv = (char**)NULL;
if(argc)
{
targv = new char*[argc];
for(int k=0;k<argc;k++)
{
targv[k] = new char[strlen(argv[k])+1];
strcpy(targv[k],argv[k]);
}
}
CS = cs;
DS = ds;
BSS = bss;
int db = DS + BSS;
int n = db / PAGE_SIZE;
if(db % PAGE_SIZE) n++;
HEAP = (n*PAGE_SIZE - (DS+BSS)) + PAGE_SIZE;
SS = ss;
int t = CS + DS + BSS + HEAP + SS;
int total = mm.prog_pages * PAGE_SIZE;
entry_point = ep;
int sz = _FAT_driver.lseek(fd,0,SEEK_END);
_FAT_driver.lseek(fd,0,SEEK_SET);
if(t <= total)
{
// the new mem of process fits in old area
}
else
{
total = t;
delete mm.virtual_page;
delete mm.physical_page;
_paging_obj.free_pages(physical_base);
physical_base = NULL;
mm.prog_pages = total / PAGE_SIZE;
if(total % PAGE_SIZE) mm.prog_pages++;
mm.virtual_page = new uint[mm.prog_pages];
mm.physical_page = new uint[mm.prog_pages];
physical_base = _paging_obj.alloc_pages(mm.prog_pages);
set_cs(ldt[0]);
set_ds(ldt[1]);
set_mem_map();
set_table_entries();
}
// if(_FAT_driver.read(fd,(void*)__VIRTUAL_BASE,sz) != sz) return -1;
// _heap.init_heap(__VIRTUAL_BASE+CS+DS+BSS,HEAP);
if(_FAT_driver.read(fd,physical_base,sz) != sz) return -1;
_heap.init_heap((uint)physical_base+CS+DS+BSS,HEAP);
char **mmargv;
mmargv = (char**)_heap.malloc(argc*sizeof(char*));
for(int i=0;i<argc;i++)
{
mmargv[i] = (char*)_heap.malloc(strlen(argv[i])+1);
strcpy(mmargv[i],targv[i]);
// mmargv[i] = (char*)((uint)mmargv[i] - __VIRTUAL_BASE);
mmargv[i] = (char*)((uint)mmargv[i] - (uint)physical_base);
}
int envcnt = 0;
char **tmp = environ;
while(*tmp)
{
envcnt++;
tmp++;
}
char **mmenv;
mmenv = (char**)_heap.malloc(envcnt*sizeof(char*));
for(int i=0;i<envcnt;i++)
{
mmenv[i] = (char*)_heap.malloc(strlen(environ[i])+1);
strcpy(mmenv[i],environ[i]);
// mmenv[i] = (char*)((uint)mmenv[i] - __VIRTUAL_BASE);
mmenv[i] = (char*)((uint)mmenv[i] - (uint)physical_base);
}
uint stk_top = mm.prog_pages * PAGE_SIZE - 1;
/* set_tss(0,argc,((uint)mmargv - __VIRTUAL_BASE),((uint)mmenv - __VIRTUAL_BASE),
0,0,0,_ds_sel,_ds_sel,_ds_sel,_ds_sel,entry_point,_cs_sel,0x202,
stk_top,_ds_sel);*/
set_tss(0,argc,mmargv ? ((uint)mmargv - (uint)physical_base) : 0,
mmenv ? ((uint)mmenv - (uint)physical_base) : 0,
0,0,0,_ds_sel,_ds_sel,_ds_sel,_ds_sel,
entry_point,_cs_sel,0x202,stk_top,_ds_sel);
for(int m=0;m<argc;m++)
delete targv[m];
delete targv;
return 0;
}
void memory::clear()
{
delete mm.virtual_page;
delete mm.physical_page;
_paging_obj.free_pages(physical_base);
physical_base = NULL;
}
void memory::show_tss()
{
cout<<"tss selector :"<<_tss_sel<<endl;
cout<<"esp0 :"<<tss.esp0<<endl;
cout<<"ss0 :"<<tss.ss0<<endl;
cout<<"cr3 :"<<tss.cr3<<endl;
cout<<"eip :"<<tss.eip<<endl;
cout<<"eflags :"<<tss.eflag<<endl;
cout<<"esp :"<<tss.esp<<endl;
cout<<"ebp :"<<tss.ebp<<endl;
cout<<"edi :"<<tss.edi<<endl;
cout<<"esi :"<<tss.esi<<endl;
cout<<"edx :"<<tss.edx<<endl;
cout<<"ecx :"<<tss.ecx<<endl;
cout<<"ebx :"<<tss.ebx<<endl;
cout<<"eax :"<<tss.eax<<endl;
cout<<"cs :"<<tss.cs<<endl;
cout<<"ds :"<<tss.ds<<endl;
cout<<"ss :"<<tss.ss<<endl;
cout<<"es :"<<tss.es<<endl;
cout<<"fs :"<<tss.fs<<endl;
cout<<"gs :"<<tss.gs<<endl;
cout<<"ldt :"<<tss.ldt<<endl;
}
void memory::show_ldt()
{
seg_desc *d = &ldt[0];
uint _b = (d->base_high<<24 | d->base_mid<<16 | d->base_low);
cout<<"cs base :"<<_b<<endl;
cout<<"cs limit:"<<d->lim_low<<endl;
cout<<"cs access:"<<d->access<<endl;
d = &ldt[1];
_b = (d->base_high<<24 | d->base_mid<<16 | d->base_low);
cout<<"ds base :"<<_b<<endl;
cout<<"ds limit:"<<d->lim_low<<endl;
cout<<"ds access:"<<d->access<<endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -