//! kernel entry point is called by boot loader void __cdecl kernel_entry (multiboot_info* bootinfo) { #ifdef ARCH_X86 // Set registers for protected mode _asm { cli mov ax, 10h mov ds, ax mov es, ax mov fs, ax mov gs, ax } #endif //ARCH_X86 //dx 레지스터에는 커널의 크기가 담겨 있다. //다른값으로 씌워지기 전에 값을 얻어낸다. _asm mov word ptr[g_kernelSize], dx InitializeConstructors(); kmain (bootinfo); Exit (); console.Print("kernel_entry : Shutdown Complete. Halting system\n"); #ifdef ARCH_X86 _asm { cli hlt } #endif for (;;); }
//프로세스 전용의 디폴트 힙을 생성한다 void CreateDefaultHeap() { EnterCriticalSection(); Process* pProcess = ProcessManager::GetInstance()->GetCurrentProcess(); Thread* pThread = pProcess->GetThread(0); //1메가 바이트의 힙을 생성 void* pHeapPhys = PhysicalMemoryManager::GetInstance()->AllocBlocks(DEFAULT_HEAP_PAGE_COUNT); u32int heapAddess = pThread->m_imageBase + pThread->m_imageSize + PAGE_SIZE + PAGE_SIZE * 2; //힙 주소를 4K에 맞춰 Align heapAddess -= (heapAddess % PAGE_SIZE); #ifdef _ORANGE_DEBUG console.Print("heap adress %x\n", heapAddess); #endif // _ORANGE_DEBUG for (int i = 0; i < DEFAULT_HEAP_PAGE_COUNT; i++) { VirtualMemoryManager::GetInstance()->MapPhysicalAddressToVirtualAddresss(pProcess->m_pPageDirectory, (uint32_t)heapAddess + i * PAGE_SIZE, (uint32_t)pHeapPhys + i * PAGE_SIZE, I86_PTE_PRESENT | I86_PTE_WRITABLE | I86_PTE_USER); } memset((void*)heapAddess, 0, DEFAULT_HEAP_PAGE_COUNT * PAGE_SIZE); pProcess->m_lpHeap = create_heap((u32int)heapAddess, (uint32_t)heapAddess + DEFAULT_HEAP_PAGE_COUNT * PAGE_SIZE, (uint32_t)heapAddess + DEFAULT_HEAP_PAGE_COUNT * PAGE_SIZE, 0, 0); LeaveCriticalSection(); }
bool ConsoleManager::RunCommand(char* buf) { if (strcmp(buf, "user") == 0) { go_user(); } //! exit command if (strcmp(buf, "exit") == 0) { return true; } //! clear screen else if (strcmp(buf, "cls") == 0) { console.Clear(); } //! help else if (strcmp(buf, "help") == 0) { console.Print("Orange OS Console Help\n"); console.Print(" - exit: quits and halts the system\n"); console.Print(" - cls: clears the display\n"); console.Print(" - help: displays this message\n"); console.Print(" - read: reads a file\n"); console.Print(" - reset: Resets and recalibrates floppy for reading\n"); console.Print(" - proc: Run process\n"); } //! read sector else if (strcmp(buf, "read") == 0) { cmd_read(); } else if (strcmp(buf, "memstate") == 0) { cmd_memstate(); } else if (strcmp(buf, "alloc") == 0) { cmd_alloc(); } else if (strcmp(buf, "memtask") == 0) { cmd_memtask(); } //! run process else if (strcmp(buf, "proc") == 0) { cmd_proc(); } else { console.Print("Unknown Command\n"); } return false; }
uint32_t MemoryAlloc(size_t size) { Process* pProcess = ProcessManager::GetInstance()->GetCurrentProcess(); void *addr = alloc(size, (u8int)0, (heap_t*)pProcess->m_lpHeap); #ifdef _ORANGE_DEBUG console.Print("process heap alloc, %d %x\n", size, pProcess->m_lpHeap); console.Print("process heap alloc, %d %x\n", size, pProcess->m_lpHeap); #endif return (u32int)addr; }
//! divide by 0 fault void _cdecl divide_by_zero_fault (uint32_t eflags,uint32_t cs,uint32_t eip, uint32_t other) { _asm { cli add esp, 12 pushad } console.Print("Divide by 0 at physical address[0x%x:0x%x] EFLAGS[0x%x] other: 0x%x",cs, eip, eflags, other); //kernel_panic ("Divide by 0 at physical address [0x%x:0x%x] EFLAGS [0x%x] other: 0x%x",cs,eip, eflags, other); for (;;); }
//프로세스 종료 extern "C" void TerminateProcess() { EnterCriticalSection(); Process* cur = ProcessManager::GetInstance()->GetCurrentProcess(); if (cur == NULL || cur->m_processId == PROC_INVALID_ID) { console.Print("Invailid Process Termination\n"); return; } //프로세스 매니저에서 해당 프로세스를 완전히 제거한다. //태스크 목록에서도 제거되어 해당 프로세스는 더이상 스케쥴링 되지 않는다. ProcessManager::GetInstance()->DestroyProcess(cur); LeaveCriticalSection(); for (;;); }
bool Scheduler::DoSchedule(int tick, uint32_t registers) { //DebugPrintf("\nScheduler"); int entryPoint = 0; unsigned int procStack = 0; /* switch to process address space */ if (systemOn == true) { Process* curProcess = ProcessManager::GetInstance()->g_pCurProcess; if (curProcess) { Thread* pCurThread = (Thread*)List_GetData(curProcess->pThreadQueue, "", 0); pCurThread->curESP = (*(uint32_t*)(registers - 8)); pCurThread->curFlags = (*(uint32_t*)(registers - 12)); pCurThread->curCS = (*(uint32_t*)(registers - 16)); pCurThread->curEip = (*(uint32_t*)(registers - 20)); /*pCurThread->curgs = (*(uint16_t*)(registers - 24)); pCurThread->curfs = (*(uint16_t*)(registers - 28)); pCurThread->curEs = (*(uint16_t*)(registers - 32)); pCurThread->curds = (*(uint16_t*)(registers - 36));*/ pCurThread->frame.eax = (*(uint32_t*)(registers - 24)); pCurThread->frame.ecx = (*(uint32_t*)(registers - 28)); pCurThread->frame.edx = (*(uint32_t*)(registers - 32)); pCurThread->frame.ebx = (*(uint32_t*)(registers - 36)); pCurThread->frame.esp = (*(uint32_t*)(registers - 40)); pCurThread->frame.ebp = (*(uint32_t*)(registers - 44)); pCurThread->frame.esi = (*(uint32_t*)(registers - 48)); pCurThread->frame.edi = (*(uint32_t*)(registers - 52)); LISTNODE *pProcessList = ProcessManager::GetInstance()->pProcessQueue; int processCount = List_Count(pProcessList); for (int index = 0; index < processCount; index++) { Process* pProcess = (Process*)List_GetData(pProcessList, "", index); if (curProcess == pProcess) continue; pProcess->dwTickCount++; if (pProcess->dwTickCount > 10) { pProcess->dwTickCount = 0; if (pProcess->dwProcessType == PROCESS_USER) { console.Print("Scheduler1 : %d\n", processCount); ProcessManager::GetInstance()->g_pCurProcess = pProcess; Thread* pThread = (Thread*)List_GetData(pProcess->pThreadQueue, "", 0); entryPoint = pThread->curEip; procStack = pThread->curESP; uint32_t eflags = pThread->curFlags; console.Print("eip : %x\n", pThread->curEip); console.Print("CS : %x\n", pThread->curCS); console.Print("flags : %x\n", pThread->curFlags); console.Print("esp : %x\n", pThread->curESP); //entryPoint = pThread->frame.eip; //procStack = pThread->frame.esp; uint32_t regEax = pThread->frame.eax; uint32_t regEcx = pThread->frame.ecx; uint32_t regEdx = pThread->frame.edx; uint32_t regEbx = pThread->frame.ebx; uint32_t regEsp = pThread->frame.esp; uint32_t regEbp = pThread->frame.ebp; uint32_t regEsi = pThread->frame.esi; uint32_t regEdi = pThread->frame.edi; uint16_t regGs = pThread->curgs; uint16_t regFs = pThread->curfs; uint16_t regEs = pThread->curEs; uint16_t regDs = pThread->curds; pmmngr_load_PDBR((physical_addr)pProcess->pPageDirectory); OutPortByte(0x20, 0x20); __asm { mov ax, 0x23; user mode data selector is 0x20 (GDT entry 3).Also sets RPL to 3 mov ds, ax mov es, ax mov fs, ax mov gs, ax ; create stack frame ; push 0x23; SS, notice it uses same selector as above push[procStack]; stack push[eflags]; EFLAGS push 0x1b; CS, user mode code selector is 0x18.With RPL 3 this is 0x1b push[entryPoint]; EIP mov eax, regEax mov ecx, regEcx mov edx, regEdx mov ebx, regEbx mov esp, regEsp mov ebp, regEbp mov esi, regEsi mov edi, regEdi iretd } } else { /*if (aa == 0) { aa = 1; DebugPrintf("\nasdasas : %x", registers); for (int i = 0; i < 20; i++) DebugPrintf("\nasdasas : %x", (*(uint32_t*)(registers - i * 4))); while (1); }*/ console.Print("Scheduler2\n"); ProcessManager::GetInstance()->g_pCurProcess = pProcess; Thread* pThread = (Thread*)List_GetData(pProcess->pThreadQueue, "", 0); entryPoint = pThread->frame.eip; procStack = pThread->frame.esp; //procStack = 0; pmmngr_load_PDBR((physical_addr)pProcess->pPageDirectory); OutPortByte(0x20, 0x20); __asm { mov ax, 0x10; mov ds, ax mov es, ax mov fs, ax mov gs, ax ; ; create stack frame ; push 0x10; SS, notice it uses same selector as above push[procStack]; stack push 0x200; EFLAGS push 0x08; push[entryPoint]; EIP iretd } } }