Page 1 of 1

Strange Interrupt Code

Posted: Wed Feb 20, 2008 7:05 pm
by kg4mxz
I am writing a basic kernel following JamesM's tutorial with slightly modified code. I was testing the Exception Handler by dividing by zero and I end up with an endless chain of isr_handler with r->int_code = 0xc00000e6 unless I add an "asm volatile ("hlt")" at the end of my isr_handler statement, at which point I still get one interrupt code 0xc00000e6 instead of the expected 0x0000000. Any idea as to what might be causing this? I am running the kernel on bochs running in ubuntu within VMWare on top of WinXP

Posted: Wed Feb 20, 2008 7:37 pm
by t0xic
I am running the kernel on bochs running in ubuntu within VMWare on top of WinXP
Are you serious? Back on topic, I would check the assembly code to make sure that the registers are being pushed in the correct order

Posted: Wed Feb 20, 2008 7:44 pm
by kg4mxz
Dead serious :D

The assembly looks fine to me... here is what I have:

No Error Code Macro:

Code: Select all

%macro ISR_NOERRCODE 1
  global isr%1
  isr%1:
    cli                         ; Disable interrupts firstly.
    push byte 0                 ; Push a dummy error code.
    push byte %1                ; Push the interrupt number.
    jmp isr_common_stub         ; Go to our common handler code.
%endmacro
Using the macro:

Code: Select all

ISR_NOERRCODE 0
jump to isr_common_stub:

Code: Select all

isr_common_stub:
    pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax

    mov ax, ds               ; Lower 16-bits of eax = ds.
    push eax                 ; save the data segment descriptor

    mov ax, 0x10  ; load the kernel data segment descriptor
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    call isr_handler

    pop ebx        ; reload the original data segment descriptor
    mov ds, bx
    mov es, bx
    mov fs, bx
    mov gs, bx

    popa                     ; Pops edi,esi,ebp...
    add esp, 8     ; Cleans up the pushed error code and pushed ISR number
    sti
    iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
EDIT - Almost forgot:

Code: Select all


void isr_handler(struct regs *r)
{
printf("Handling ISR!\n");
printf("%h",r->int_no);


    /* Is this a fault whose number is from 0 to 31? */
    if (r->int_no < 32)
    {

        /* Display the description for the Exception that occurred.
        *  In this tutorial, we will simply halt the system using an
        *  infinite loop */

	PANIC(exception_messages[r->int_no]);

    }
//asm volatile ("hlt");
}

Code: Select all

struct regs
{
    u32int gs, fs, es, ds;
    u32int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    u32int int_no, err_code;
    u32int eip, cs, eflags, useresp, ss;
};

Posted: Wed Feb 20, 2008 7:49 pm
by os.hacker64
I bet it runs pretty slow. :shock: :D

Posted: Wed Feb 20, 2008 7:53 pm
by kg4mxz
It has plenty of ram and a dual core processor, it really isn't so bad actually... remember, the most complex (working) thing in my kernel right now is printf, so I would hope that doesnt tax the emulated emulated cpu too much :)

Posted: Thu Feb 21, 2008 2:35 am
by JamesM
Hi,

Code: Select all

struct regs
{
    u32int gs, fs, es, ds;
    u32int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    u32int int_no, err_code;
    u32int eip, cs, eflags, useresp, ss;
}; 
This is wrong. gs, fs and es are never pushed. Look at your code. It *should* be:

Code: Select all

struct regs
{
    u32int ds;
    u32int edi, esi, ebp, esp, ebx, edx, ecx, eax;
    u32int int_no, err_code;
    u32int eip, cs, eflags, useresp, ss;
};
Hope this helps.

James

Posted: Thu Feb 21, 2008 6:56 pm
by kg4mxz
Problem solved!

Thanks a lot for the help guys and props to James for the excellent tutorials.