help with ISRs crashing machine

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

help with ISRs crashing machine

Post 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
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: help with ISRs crashing machine

Post by AndrewAPrice »

anyone?
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: help with ISRs crashing machine

Post 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"
Fabba
Posts: 2
Joined: Sat Jun 10, 2006 11:00 pm
Location: germany

Re: help with ISRs crashing machine

Post 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
User avatar
AndrewAPrice
Member
Member
Posts: 2309
Joined: Mon Jun 05, 2006 11:00 pm
Location: USA (and Australia)

Re: help with ISRs crashing machine

Post 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!
Post Reply