Currently I am making a x86 custom OS with C++.
Somedays ago, I added interrupt handler and enalbed interrupt.
However, general portection fault occures after interrupt is enabled.
So, I added some debugging code to find where the GPF generates.
When a GPF happens, this assembly code is executed.
Code: Select all
; #13, General Protection ISR
_kISRGeneralProtection:
KSAVECONTEXT ; Store the context and change selector to
; kernel data descriptor
; Insert exception number and error code to the hander and call the handler
mov rdi, 13
mov rsi, qword [rbp + 8]
mov rdx, qword [rbp + 16]
mov rcx, qword [rbp + 24]
call _kCommonExceptionHandler
KLOADCONTEXT ; Restore the context
add rsp, 8 ; Remove error code from stack
iretq ; Return the event point after interrupt
; handling
They are the interrupt vector number, the error code, the RIP, and the CS.
The below code show how to print the values.
Code: Select all
void kUtils::kPrintException(const char* pcVectorNumber,
const char* pcErrorCode,
const char* pcRIP,
const char* pcCS)
{
kPrintString(0, 0,
"===========================================================");
kPrintString(0, 1,
" Exception Occur ");
kPrintString(0, 2,
" Vector: ");
kPrintString(0, 3,
" Error Code: 0x ");
kPrintString(0, 4,
" RIP: 0x ");
kPrintString(0, 5,
" CS: 0x ");
kPrintString(0, 6,
"===========================================================");
kPrintString(26, 2, pcVectorNumber);
kPrintString(28, 3, pcErrorCode);
kPrintString(28, 4, pcRIP);
kPrintString(28, 5, pcCS);
return;
}
void kIH::kDecodeError(unsigned long qwCode, char* cMean)
{
unsigned long ulMask = 0xF;
unsigned long ulValue;
char c;
for (int i = 0; i < 16; i++)
{
ulValue = qwCode & ulMask;
if (ulValue > 9)
{
c = 'A' + ulValue - 10;
}
else
{
c = '0' + ulValue;
}
cMean[15 - i] = c;
qwCode = qwCode >> 4;
}
return;
}
// Common exception handler
void kIH::kCommonExceptionHandler(int iVectorNumber, unsigned long qwErrorCode, unsigned long qwRIP, unsigned long qwCS)
{
char cNumber[3] = { 0, };
char cErrorCode[17] = { 0, };
char cRIP[17] = {0, };
char cCS[17] = {0, };
// Print interrupt vector number as 2 digit number
cNumber[0] = '0' + iVectorNumber / 10;
cNumber[1] = '0' + iVectorNumber % 10;
kDecodeError(qwErrorCode, cErrorCode);
kDecodeError(qwRIP, cRIP);
kDecodeError(qwCS, cCS);
g_pclUtils->kPrintException(cNumber, cErrorCode, cRIP, cCS);
while (1);
}
Code: Select all
Vector: 13
Error Code: 0x000000000020139D
RIP: 0x00000000007FFFD0
CS: 0x000000000000FF18
What did I make a mistake? And in this case, how can I get an useful information from error code?