Page 1 of 1

help with ISRs crashing machine

Posted: Mon Jun 05, 2006 11:00 pm
by AndrewAPrice
I have re-written my ISR/IDT handling system and now everytime I an interrupt is fired the system will either crash (Qemu) or reboot (Bochs). I would revert back to my old code except for the fact that I didn't make a backup.

Here is my IDT code:

Code: Select all

; idt

; setup the IDT
IDT_init:

        ; exceptions to go here too

        mov ebx, 0x20    ; timer
        mov ecx, [_irq0]
        call IDT_addint

        mov ebx, 0x21    ; keyboard
        mov ecx, [_irq1]
        call IDT_addint

        lidt [IDT_list]
        sti
        ret

IDT_list:
rept 256 ; repeat 256 times (FASM style loop)
{
        dw 0                     ; offset
        dw 0x0008                ; kernel segment
        db 00000000b
        db 00001110b            ; 1st byte = is segment present
        dw 0                     ; offset
}
IDT_listend:

IDT_listpointer:   dw IDT_listend - IDT_list - 1
                   dd IDT_list

; add an idt entry, ebx = int number, ecx = pointer to function
IDT_addint:
        mov esi, ecx
        and esi, 0xFFFF
        mov eax, esi
        mov edi, [(IDT_list + (ebx * 8))]
        mov [edi], ax

        mov esi, ecx
        mov eax, esi
        shr eax, 16
        mov [edi + 6], ax

        mov ax, 00001110b
        mov [edi + 6], ax

        ret
Here are my ISR handlers:

Code: Select all

; 32: IRQ0
_irq0:
    cli
    push  0
    push  32
    jmp irq_common_stub

; 33: IRQ1
_irq1:
    cli
    push  0
    push  33
    jmp irq_common_stub

irq_common_stub:
    pusha
    push ds
    push es
    push fs
    push gs

;    push eax
;    mov eax, [handle_irq]
;    call eax
;    pop eax

    call cls ; clear the screen, useless but I just want to get it working ATM

    pop gs
    pop fs
    pop es
    pop ds
    popa
    add esp, 8
    iret   
Code to enable IRQ0:

Code: Select all

Timer_enable:
        mov cl, 0
        call IRQ_enable
        ret   
Code to enable IRQ1:

Code: Select all

Keyboard_enable:
        mov cl, 1
        call IRQ_enable
        ret       
PICs/Enable IRQS:

Code: Select all

PICs_remap:
        mov al, 0x11
        out 0x20, al
        out 0xA0, al

        mov al, 0x20
        out 0x21, al

        mov al, 0x28
        out 0xA1, al

        mov al, 0x04
        out 0x21, al

        mov al, 0x02
        out 0xA1, al

        mov al, 0x01
        out 0x21, al
        out 0xA1, al

        mov al, 0xFF
        out 0x21, al

        mov al, 0xFB
        out 0xA1, al
        ret

; enable IRQ, cl = irq
IRQ_enable:
          push    ax
          push    cx

          cmp     cl, 8
          jb      .IRQ_enable_master

          sub     cl, 8
          mov     ah, 1
          shl     ah, cl
          xor     ah, 0xFF

          in      al, 0xA1
          and     al, ah
          out     0xA1, al

          pop     cx
          pop     ax
          ret
  .IRQ_enable_master:
          mov     ah, 1
          shl     ah, cl
          xor     ah, 0xFF

          in      al, 0x21
          and     al, ah
          out     0x21, al

          pop     cx
          pop     ax
          ret
snippet from my start function

Code: Select all

        lgdt [GDT_pointer]

        call PICs_remap

;       call Timer_init     ; set timer to 100Hz

        call IDT_init

;        call Timer_enable  ; commented out for now
         call Keyboard_enable

Re: help with ISRs crashing machine

Posted: Tue Jun 06, 2006 11:00 pm
by AndrewAPrice
anyone?

Re: help with ISRs crashing machine

Posted: Wed Jun 07, 2006 11:00 pm
by Dex
Quick look i would try, first setting nonone handle int to a dummy function, to see what append, next is kernel segment code segment, and not data by mistake.

Next try something like this in the code and see where it stops.

Code: Select all

	mov   byte [es:0xB809E], "1"

Code: Select all

	mov   byte [es:0xB809E], "2"

Code: Select all

	mov   byte [es:0xB809E], "3"

Re: help with ISRs crashing machine

Posted: Sat Jun 10, 2006 11:00 pm
by Fabba
the first thing i notice is that you use

Code: Select all

mov ecx, [_irq0]
before calling your IDT_addint procedure
this moves the dword located at the address of _irq0 into ecx
you probably rather want to

Code: Select all

mov ecx, _irq0
or (depending on the assembler)

Code: Select all

mov ecx, offset _irq0
instead - to move the handler's address there

if it still doesn't work then, adding lots of debug messages that output stuff to the screen like Dex said, and running your code part-wise (adding jmp $ in different positions) should help track down the problem more exactly

Re: help with ISRs crashing machine

Posted: Sat Jun 10, 2006 11:00 pm
by AndrewAPrice
Thank you! My IDT is working now.

I took the [ and ]'s from

Code: Select all

mov ecx, [_irq0]
and I moved

Code: Select all

lidt [IDT_listpointer]
to before my kernel enters protected mode. It works perfectly now!

Dex's

Code: Select all

	mov   byte [es:0xB809E], "1"
tip is great! Thanks again!