// 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) { }