参考
https://blog.51cto.com/13475106/category6.html及狄泰软件相关课程
主要代码文件
%include "common.asm" global _start global TimerHandlerEntry extern TimerHandler extern gCTaskAddr extern gGdtInfo extern gIdtInfo extern InitInterrupt extern EnableTimer extern SendEOI extern RunTask extern KMain extern ClearScreen %macro BeginISR 0 sub esp, 4 pushad push ds push es push fs push gs mov dx, ss mov ds, dx mov es, dx mov esp, BaseOfLoader %endmacro %macro EndISR 0 mov esp, [gCTaskAddr] pop gs pop fs pop es pop ds popad add esp, 4 iret %endmacro [section .text] [bits 32] _start: mov ebp, 0 call InitGlobal call ClearScreen call KMain jmp $ ; ; InitGlobal: push ebp mov ebp, esp mov eax, dword [GdtEntry] mov [gGdtInfo], eax mov eax, dword [GdtSize] mov [gGdtInfo + 4], eax mov eax, dword [IdtEntry] mov [gIdtInfo], eax mov eax, dword [IdtSize] mov [gIdtInfo + 4], eax mov eax, dword [RunTaskEntry] mov dword [RunTask], eax mov eax, dword [InitInterruptEntry] mov [InitInterrupt], eax mov eax, dword [EnableTimerEntry] mov [EnableTimer], eax mov eax, dword [SendEOIEntry] mov [SendEOI], eax leave ret ; ; TimerHandlerEntry: BeginISR call TimerHandler EndISR
#include "kernel.h" #include "screen.h" #include "global.h" void (* const InitInterrupt)() = NULL; void (* const EnableTimer)() = NULL; void (* const SendEOI)(uint port) = NULL; Task* gCTaskAddr = NULL; Task p = {0}; void Delay(int n) { while( n > 0 ) { int i = 0; int j = 0; for(i=0; i<1000; i++) { for(j=0; j<1000; j++) { asm volatile ("nop\n"); } } n--; } } void TaskA() { int i = 0; SetPrintPos(0, 12); PrintString("Task A: "); while(1) { SetPrintPos(8, 12); PrintChar('A' + i); i = (i + 1) % 26; Delay(1); } } void TimerHandlerEntry(); void TimerHandler() { static uint i = 0; i = (i + 1) % 10; if( i == 0 ) { static uint j = 0; SetPrintPos(0, 13); PrintString("Timer: "); SetPrintPos(8, 13); PrintIntDec(j++); } SendEOI(MASTER_EOI_PORT); } void KMain() { int n = PrintString("D.T.OS\n"); uint temp = 0; PrintString("GDT Entry: "); PrintIntHex((uint)gGdtInfo.entry); PrintChar('\n'); PrintString("GDT Size: "); PrintIntDec((uint)gGdtInfo.size); PrintChar('\n'); PrintString("IDT Entry: "); PrintIntHex((uint)gIdtInfo.entry); PrintChar('\n'); PrintString("IDT Size: "); PrintIntDec((uint)gIdtInfo.size); PrintChar('\n'); p.rv.cs = LDT_CODE32_SELECTOR; p.rv.gs = LDT_VIDEO_SELECTOR; p.rv.ds = LDT_DATA32_SELECTOR; p.rv.es = LDT_DATA32_SELECTOR; p.rv.fs = LDT_DATA32_SELECTOR; p.rv.ss = LDT_DATA32_SELECTOR; p.rv.esp = (uint)p.stack + sizeof(p.stack); p.rv.eip = (uint)TaskA; p.rv.eflags = 0x3202; p.tss.ss0 = GDT_DATA32_FLAT_SELECTOR; p.tss.esp0 = (uint)&p.rv + sizeof(p.rv); p.tss.iomb = sizeof(p.tss); SetDescValue(p.ldt + LDT_VIDEO_INDEX, 0xB8000, 0x07FFF, DA_DRWA + DA_32 + DA_DPL3); SetDescValue(p.ldt + LDT_CODE32_INDEX, 0x00, 0xFFFFF, DA_C + DA_32 + DA_DPL3); SetDescValue(p.ldt + LDT_DATA32_INDEX, 0x00, 0xFFFFF, DA_DRW + DA_32 + DA_DPL3); p.ldtSelector = GDT_TASK_LDT_SELECTOR; p.tssSelector = GDT_TASK_TSS_SELECTOR; SetDescValue(&gGdtInfo.entry[GDT_TASK_LDT_INDEX], (uint)&p.ldt, sizeof(p.ldt)-1, DA_LDT + DA_DPL0); SetDescValue(&gGdtInfo.entry[GDT_TASK_TSS_INDEX], (uint)&p.tss, sizeof(p.tss)-1, DA_386TSS + DA_DPL0); SetIntHandler(gIdtInfo.entry + 0x20, (uint)TimerHandlerEntry); InitInterrupt(); EnableTimer(); gCTaskAddr = &p; RunTask(gCTaskAddr); }