void TerminateProcess () { process* cur = &_proc; if (cur->id==PROC_INVALID_ID) return; /* release threads */ int i=0; thread* pThread = &cur->threads[i]; /* get physical address of stack */ void* stackFrame = vmmngr_getPhysicalAddress (cur->pageDirectory, (uint32_t) pThread->initialStack); /* unmap and release stack memory */ vmmngr_unmapPhysicalAddress (cur->pageDirectory, (uint32_t) pThread->initialStack); pmmngr_free_block (stackFrame); /* unmap and release image memory */ for (uint32_t page = 0; page < pThread->imageSize/PAGE_SIZE; page++) { uint32_t phys = 0; uint32_t virt = 0; /* get virtual address of page */ virt = pThread->imageBase + (page * PAGE_SIZE); /* get physical address of page */ phys = (uint32_t) vmmngr_getPhysicalAddress (cur->pageDirectory, virt); /* unmap and release page */ vmmngr_unmapPhysicalAddress (cur->pageDirectory, virt); pmmngr_free_block ((void*)phys); } /* restore kernel selectors */ __asm { cli mov eax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax sti } /* return to kernel command shell */ run (); DebugPrintf ("\nExit command recieved; demo halted"); for (;;); }
void vmmngr_free_page(virtual_addr addr) { pt_entry * pte; pte = (pt_entry *) ((uint32_t) vmmngr_get_ptable_address(addr) + PAGE_TABLE_INDEX(addr)); pmmngr_free_block((void *) pt_entry_pfn(*pte)); pt_entry_del_attrib(pte, I86_PTE_PRESENT); }
error_t vmmngr_pdirectory_clear(pdirectory* pdir) { for (int i = 0; i < TABLES_PER_DIR; i++) { if (vmmngr_ptable_clear((ptable*)pd_entry_get_frame(pdir->entries[i])) != ERROR_OK) return ERROR_OCCUR; } memset(pdir, 0, sizeof(pdirectory)); pmmngr_free_block(pdir); return ERROR_OK; }
error_t vmmngr_ptable_clear(ptable* table) { if (!table) { set_last_error(EINVAL, VMEM_BAD_ARGUMENT, EO_VMMNGR); return ERROR_OCCUR; } memset(table, 0, sizeof(ptable)); pmmngr_free_block(table); return ERROR_OK; }
error_t vmmngr_free_page(pt_entry* entry) { if (!entry) { set_last_error(EINVAL, VMEM_BAD_ARGUMENT, EO_VMMNGR); return ERROR_OCCUR; } void* addr = (void*)pt_entry_get_frame(*entry); if (addr) pmmngr_free_block(addr); pt_entry_del_attrib(entry, I86_PTE_PRESENT); pt_entry_del_attrib(entry, I86_PTE_WRITABLE); return ERROR_OK; }
int _cdecl kmain (multiboot_info* bootinfo) { //! get kernel size passed from boot loader uint32_t kernelSize=0; _asm mov word ptr [kernelSize], dx //! make demo look nice :) DebugClrScr (0x13); DebugGotoXY (0,0); DebugSetColor (0x3F); DebugPrintf (" ~[ Physical Memory Manager Demo ]~ "); DebugGotoXY (0,24); DebugSetColor (0x3F); DebugPrintf (" "); DebugGotoXY (0,2); DebugSetColor (0x17); //! initialize hal hal_initialize (); //! enable interrupts and install exception handlers enable (); setvect (0,(void (__cdecl &)(void))divide_by_zero_fault); setvect (1,(void (__cdecl &)(void))single_step_trap); setvect (2,(void (__cdecl &)(void))nmi_trap); setvect (3,(void (__cdecl &)(void))breakpoint_trap); setvect (4,(void (__cdecl &)(void))overflow_trap); setvect (5,(void (__cdecl &)(void))bounds_check_fault); setvect (6,(void (__cdecl &)(void))invalid_opcode_fault); setvect (7,(void (__cdecl &)(void))no_device_fault); setvect (8,(void (__cdecl &)(void))double_fault_abort); setvect (10,(void (__cdecl &)(void))invalid_tss_fault); setvect (11,(void (__cdecl &)(void))no_segment_fault); setvect (12,(void (__cdecl &)(void))stack_fault); setvect (13,(void (__cdecl &)(void))general_protection_fault); setvect (14,(void (__cdecl &)(void))page_fault); setvect (16,(void (__cdecl &)(void))fpu_fault); setvect (17,(void (__cdecl &)(void))alignment_check_fault); setvect (18,(void (__cdecl &)(void))machine_check_abort); setvect (19,(void (__cdecl &)(void))simd_fpu_fault); //! get memory size in KB uint32_t memSize = 1024 + bootinfo->m_memoryLo + bootinfo->m_memoryHi*64; //! initialize the physical memory manager //! we place the memory bit map used by the PMM at the end of the kernel in memory pmmngr_init (memSize, 0x100000 + kernelSize*512); DebugPrintf("pmm initialized with %i KB physical memory; memLo: %i memHi: %i\n\n", memSize,bootinfo->m_memoryLo,bootinfo->m_memoryHi); DebugSetColor (0x19); DebugPrintf ("Physical Memory Map:\n"); memory_region* region = (memory_region*)0x1000; for (int i=0; i<15; ++i) { //! sanity check; if type is > 4 mark it reserved if (region[i].type>4) region[i].type=1; //! if start address is 0, there is no more entries, break out if (i>0 && region[i].startLo==0) break; //! display entry DebugPrintf ("region %i: start: 0x%x%x length (bytes): 0x%x%x type: %i (%s)\n", i, region[i].startHi, region[i].startLo, region[i].sizeHi,region[i].sizeLo, region[i].type, strMemoryTypes[region[i].type-1]); //! if region is avilable memory, initialize the region for use if (region[i].type==1) pmmngr_init_region (region[i].startLo, region[i].sizeLo); } //! deinit the region the kernel is in as its in use pmmngr_deinit_region (0x100000, kernelSize*512); DebugSetColor (0x17); DebugPrintf ("\npmm regions initialized: %i allocation blocks; used or reserved blocks: %i\nfree blocks: %i\n", pmmngr_get_block_count (), pmmngr_get_use_block_count (), pmmngr_get_free_block_count () ); //! allocating and deallocating memory examples... DebugSetColor (0x12); uint32_t* p = (uint32_t*)pmmngr_alloc_block (); DebugPrintf ("\np allocated at 0x%x", p); uint32_t* p2 = (uint32_t*)pmmngr_alloc_blocks (2); DebugPrintf ("\nallocated 2 blocks for p2 at 0x%x", p2); pmmngr_free_block (p); p = (uint32_t*)pmmngr_alloc_block (); DebugPrintf ("\nUnallocated p to free block 1. p is reallocated to 0x%x", p); pmmngr_free_block (p); pmmngr_free_blocks (p2, 2); return 0; }
void TerminateProcess () { Process* cur = ProcessManager::GetInstance()->g_pCurProcess; if (cur->TaskID == PROC_INVALID_ID) { DebugPrintf("\nsdffdsdsfsd"); return; } /* release threads */ int i=0; //Thread* pThread = ProcessManager::GetInstance()->g_pThread; Thread* pThread = (Thread*)List_GetData(cur->pThreadQueue, "", 0); List_Delete(&cur->pThreadQueue, "", 0); u32int heapAddess = pThread->imageBase + pThread->imageSize + PAGE_SIZE + PAGE_SIZE * 2; heapAddess = heapAddess - (heapAddess % PAGE_SIZE); for (int i = 0; i < 300; i++) { uint32_t phys = 0; uint32_t virt = 0; /* get virtual address of page */ virt = heapAddess + (i * PAGE_SIZE); /* get physical address of page */ phys = (uint32_t)vmmngr_getPhysicalAddress(cur->pPageDirectory, virt); /* unmap and release page */ vmmngr_unmapPhysicalAddress(cur->pPageDirectory, virt); } /* unmap and release image memory */ for (uint32_t page = 0; page < cur->dwPageCount; page++) { uint32_t phys = 0; uint32_t virt = 0; /* get virtual address of page */ virt = pThread->imageBase + (page * PAGE_SIZE); /* get physical address of page */ phys = (uint32_t)vmmngr_getPhysicalAddress(cur->pPageDirectory, virt); /* unmap and release page */ vmmngr_unmapPhysicalAddress(cur->pPageDirectory, virt); //pmmngr_free_block ((void*)phys); } /* get physical address of stack */ void* stackFrame = vmmngr_getPhysicalAddress(cur->pPageDirectory, (uint32_t)pThread->initialStack); /* unmap and release stack memory */ vmmngr_unmapPhysicalAddress(cur->pPageDirectory, (uint32_t)pThread->initialStack); //pmmngr_free_block(stackFrame); pmmngr_free_block(cur->pPageDirectory); delete pThread; delete cur; /* restore kernel selectors */ __asm { cli mov eax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax sti } pmmngr_load_PDBR((physical_addr)vmmngr_get_directory()); /* return to kernel command shell */ run (); DebugPrintf ("\nExit command recieved; demo halted"); for (;;); }
void vmmngr_initialize(physical_addr dir_address) { int i = 0; int frame = 0; int virt = 0; ptable * table = (ptable *) pmmngr_alloc_block(); if (!table) { return; } ptable * table2 = (ptable *) pmmngr_alloc_block(); if (!table2) { pmmngr_free_block(table); return; } memset(table, 0, sizeof(ptable)); for (i = 0, frame = 0x0, virt = 0x00000000; i < 1024; ++i, frame+=4096, virt+=4096) { pt_entry page = 0; pt_entry_add_attrib(&page, I86_PTE_PRESENT); pt_entry_set_frame(&page, frame); table->m_entries[PAGE_TABLE_INDEX(virt)] = page; } for (i = 0, frame = 0x0, virt = 0xc0000000; i < 1024; ++i, frame+=4096, virt+=4096) { pt_entry page = 0; pt_entry_add_attrib(&page, I86_PTE_PRESENT); pt_entry_set_frame(&page, frame); table2->m_entries[PAGE_TABLE_INDEX(virt)] = page; } pdirectory * dir = (pdirectory *) dir_address;// pmmngr_alloc_block(); if (!dir) { pmmngr_free_block(table); pmmngr_free_block(table2); return; } memset(dir, 0, sizeof(pdirectory)); pd_entry * entry = &dir->m_entries[PAGE_DIRECTORY_INDEX(0x00000000)]; pd_entry_add_attrib(entry, I86_PDE_PRESENT); pd_entry_add_attrib(entry, I86_PDE_WRITABLE); pd_entry_set_frame(entry, (physical_addr) table); pd_entry * entry2 = &dir->m_entries[PAGE_DIRECTORY_INDEX(0xc0000000)]; pd_entry_add_attrib(entry2, I86_PDE_PRESENT); pd_entry_add_attrib(entry2, I86_PDE_WRITABLE); pd_entry_set_frame(entry2, (physical_addr) table2); pd_entry * entry3 = &dir->m_entries[PAGE_DIRECTORY_INDEX(0xFFC00000)]; pd_entry_add_attrib(entry3, I86_PDE_PRESENT); pd_entry_add_attrib(entry3, I86_PDE_WRITABLE); pd_entry_set_frame(entry3, (physical_addr) dir); vmmngr_switch_pdirectory(dir); pmmngr_paging_enable(1); }
int _k_main(struct multiboot_info *bootinfo) { int i; uint32_t memSize; struct memory_region* region; uint32_t *p,*p2; /*Initialize hardware drivers*/ hw_initialize(); //! install our exception handlers setvect (0, divide_by_zero_fault); setvect (1, single_step_trap); setvect (2, nmi_trap); setvect (3, breakpoint_trap); setvect (4, overflow_trap); setvect (5, bounds_check_fault); setvect (6, invalid_opcode_fault); setvect (7, no_device_fault); setvect (8, double_fault_abort); setvect (10, invalid_tss_fault); setvect (11, no_segment_fault); setvect (12, stack_fault); setvect (13, general_protection_fault); setvect (14, page_fault); setvect (16, fpu_fault); setvect (17, alignment_check_fault); setvect (18, machine_check_abort); setvect (19, simd_fpu_fault); ClrScr (0x13); GotoXY (0,0); SetColor (0x12); Puts ("\n zygote OS v0.01\n"); SetColor (0x17); /* Puts ("Enabled A20!\n"); Puts ("Initialized GDT and IDT!\n"); Puts ("Installed PIC, PIT, and exception handlers!\n"); Printf ("Cpu vender: %s \n", get_cpu_vender ());*/ //! get memory size in KB memSize = 1024 + bootinfo->m_memoryLo + bootinfo->m_memoryHi*64; //! initialize the physical memory manager //! we place the memory bit map used by the PMM at the end of the kernel in memory pmmngr_init (memSize, 0x100000); Printf("pmm initialized with %i KB physical memory; memLo: %i memHi: %i\n", memSize,bootinfo->m_memoryLo,bootinfo->m_memoryHi); SetColor (0x19); Printf ("Physical Memory Map:\n"); region = (struct memory_region*)0x1000; for (i=0; i<15; ++i) { //! sanity check; if type is > 4 mark it reserved if (region[i].type>4) region[i].type=1; //! if start address is 0, there is no more entries, break out if (i>0 && region[i].startLo==0) break; //! display entry Printf ("region %i: start: 0x%x%x length (bytes): 0x%x%x type: %i (%s)\n", i, region[i].startHi, region[i].startLo, region[i].sizeHi,region[i].sizeLo, region[i].type, strMemoryTypes[region[i].type-1]); //! if region is avilable memory, initialize the region for use if (region[i].type==1) pmmngr_init_region (region[i].startLo, region[i].sizeLo); } SetColor (0x17); Printf ("\npmm regions initialized: %i allocation blocks; used or reserved blocks: %i\nfree blocks: %i\n", pmmngr_get_block_count (), pmmngr_get_use_block_count (), pmmngr_get_free_block_count () ); //! allocating and deallocating memory examples... SetColor (0x12); p = (uint32_t*)pmmngr_alloc_block (); Printf ("\np allocated at 0x%x", p); p2 = (uint32_t*)pmmngr_alloc_blocks (2); Printf ("\nallocated 2 blocks for p2 at 0x%x", p2); pmmngr_free_block (p); p = (uint32_t*)pmmngr_alloc_block (); Printf ("\nUnallocated p to free block 1. p is reallocated to 0x%x", p); pmmngr_free_block (p); pmmngr_free_blocks (p2, 2); //To test divide by zero exception //i = 10/0; Puts ("\nHitting any key will fire the default handlers \n"); for(;;) { } };