138 lines
3.2 KiB
C
138 lines
3.2 KiB
C
|
|
// vmm.c
|
|
// Author: Josh Holtrop
|
|
// Date: 09/30/03
|
|
// Rewritten from scratch: 12/23/03
|
|
|
|
|
|
void vmm_init()
|
|
{
|
|
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
|
|
pageTables[0x3FF] = 0x104000|0x03; //the last page directory entry points to the page directory itself
|
|
if (videoMode) //we are in a graphical mode
|
|
{
|
|
dword vidPages = video_mode.XResolution * video_mode.YResolution * (video_mode.BitsPerPixel >> 3);
|
|
if (vidPages % 4096)
|
|
vidPages = (vidPages >> 12) + 1;
|
|
else
|
|
vidPages = (vidPages >> 12);
|
|
vmm_mapn(0xF0000000, video_mode.PhysBasePtr, vidPages);
|
|
}
|
|
dword firstHeapEntryBlock = (dword)mm_palloc();
|
|
vmm_map1((dword)firstHeapEntry, firstHeapEntryBlock);
|
|
HeapEntryBlock *heb = (HeapEntryBlock *)firstHeapEntry;
|
|
vmm_heb_init(heb);
|
|
heb->entry[0].base = (dword)firstHeapEntry; //start of kernel's heap memory
|
|
heb->entry[0].size = 4096; //the first HeapEntryBlock is 1 page long
|
|
heb->entry[0].attributes = VMM_HE_HEB; //this is a HeapEntryBlock
|
|
heb->entry[1].base = (dword)firstHeapEntry+4096; //this is the start of the rest of the kernel's heap memory
|
|
heb->entry[1].size = 0x10000000-4096; //the rest of the kernel's heap memory: 256mb - 4kb
|
|
heb->entry[1].attributes = VMM_HE_HOLE; //this is a hold - an unmapped section of heap memory
|
|
}
|
|
|
|
|
|
void vmm_heb_init(HeapEntryBlock *heb)
|
|
{
|
|
int a;
|
|
for (a = 0; a < 256; a++)
|
|
{
|
|
heb->entry[a].base = 0;
|
|
heb->entry[a].size = 0;
|
|
heb->entry[a].attributes = VMM_HE_UNUSED;
|
|
heb->entry[a].link = (dword)&(heb->entry[a+1]);
|
|
}
|
|
heb->entry[255].link = 0;
|
|
}
|
|
|
|
|
|
|
|
void vmm_map1(dword virt, dword physical)
|
|
{
|
|
dword pde = virt >> 22;
|
|
dword pte = (virt & 0x003FF000) >> 12;
|
|
dword *pageTables = (dword *)0xC0104000; //this is the location of the page directory
|
|
if (!(pageTables[pde] & 0x01)) //the page directory entry does not exist, we must allocate a page for it
|
|
{
|
|
dword *newpagetable = mm_palloc();
|
|
pageTables[pde] = ((dword)newpagetable) | 0x03;
|
|
invlpg(virt);
|
|
dword *newpteptr = (dword *)(0xFFC00000 | (pde << 12)); //points to first dword of newly allocated page table
|
|
int a;
|
|
for (a = 0; a < 1024; a++)
|
|
{
|
|
newpteptr[a] = 0;
|
|
}
|
|
}
|
|
dword *pteptr = (dword *)(0xFFC00000 | (pde << 12) | (pte << 2));
|
|
*pteptr = physical | 0x03;
|
|
invlpg(virt);
|
|
}
|
|
|
|
|
|
void vmm_mapn(dword virt, dword physical, dword n)
|
|
{
|
|
for (; n > 0; n--)
|
|
{
|
|
vmm_map1(virt, physical);
|
|
virt += 4096;
|
|
physical += 4096;
|
|
}
|
|
}
|
|
|
|
|
|
void vmm_unmap1(dword virt)
|
|
{
|
|
dword *pteptr = (dword *)(0xFFC00000 | ((virt & 0xFFC00000) >> 10) | ((virt & 0x003FF000) >> 10));
|
|
*pteptr = 0;
|
|
invlpg(virt);
|
|
}
|
|
|
|
|
|
void vmm_unmapn(dword virt, dword n)
|
|
{
|
|
for (; n > 0; n--)
|
|
{
|
|
vmm_unmap1(virt);
|
|
virt += 4096;
|
|
}
|
|
}
|
|
|
|
|
|
void *malloc(dword bytes)
|
|
{
|
|
HeapEntry *he = firstHeapEntry;
|
|
for (;;)
|
|
{
|
|
if ((he->size >= bytes) && (he->attributes = VMM_HE_FREE))
|
|
{
|
|
if (he->size == bytes)
|
|
{
|
|
he->attributes = VMM_HE_USED;
|
|
return (void *)(he->base);
|
|
}
|
|
else
|
|
{
|
|
//get the next HeapEntry, save in it the free mem, save in this entry the used mem...
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int free(void *ptr)
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|