Page 1 of 1

interrupts again

Posted: Mon Jun 24, 2002 11:00 pm
by Stefan
I don't understand ... how can I know with device interrupts ... on a shared irq?
When I get irq15 ... witch device interrupts? ... first drive on ide0 or the second ...

One more thing!
What is wrong with this code? ... Why does it display Double fault (8) and General protection (d)?

[org 0x7c00]
[bits 16]
    cli
    lgdt [gdtr]
    lidt [idtr]
    mov eax, cr0
    or al, 1
    mov cr0, eax
    jmp 0x0008:pm_start
[bits 32]
pm_start:
    mov ax, 0x0010
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov sp, 0x7c00
    sti

    mov cx, 80*25
    mov ebx, 0xb8000
clear_screen:
    mov [ebx], word 0x0720
    inc ebx
    inc ebx
    loop clear_screen

    int 0x20
    jmp $

exception0:
    mov [0xb8000], byte '0'
    iret

exception1:
    mov [0xb8002], byte '1'
    iret

exception2:
    mov [0xb8004], byte '2'
    iret

exception3:
    mov [0xb8006], byte '3'
    iret

exception4:
    mov [0xb8008], byte '4'
    iret

exception5:
    mov [0xb800a], byte '5'
    iret

exception6:
    mov [0xb800c], byte '6'
    iret

exception7:
    mov [0xb800e], byte '7'
    iret

exception8:
    mov [0xb8010], byte '8'
    iret

exception9:
    mov [0xb8012], byte '9'
    iret

exception10:
    mov [0xb8014], byte 'a'
    iret

exception11:
    mov [0xb8016], byte 'b'
    iret

exception12:
    mov [0xb8018], byte 'c'
    iret

exception13:
    mov [0xb801a], byte 'd'
    iret

exception14:
    mov [0xb801c], byte 'e'
    iret

exception15:
    mov [0xb801e], byte 'f'
    iret

unhand:
    iret

int20:
    mov [0xb8020], byte 'O'
    mov [0xb8022], byte 'k'
    iret

gdtr:
    dw gdt-gdtend-1
    dd gdt

idtr:
    dw idt-idtend-1
    dd idt

gdt:
  null:
    dd 0x00000000, 0x00000000
  code:
    dd 0x0000ffff, 0x00cf9a00
  data:
    dd 0x0000ffff, 0x00cf9200
gdtend:

idt:
  dw exception0, 0x0008, 0x8e00, 0x0000  ; 0x00
  dw exception1, 0x0008, 0x8e00, 0x0000  ; 0x01
  dw exception2, 0x0008, 0x8e00, 0x0000  ; 0x02
  dw exception3, 0x0008, 0x8e00, 0x0000  ; 0x03
  dw exception4, 0x0008, 0x8e00, 0x0000  ; 0x04
  dw exception5, 0x0008, 0x8e00, 0x0000  ; 0x05
  dw exception6, 0x0008, 0x8e00, 0x0000  ; 0x06
  dw exception7, 0x0008, 0x8e00, 0x0000  ; 0x07
  dw exception8, 0x0008, 0x8e00, 0x0000  ; 0x08
  dw exception9, 0x0008, 0x8e00, 0x0000  ; 0x09
  dw exception10, 0x0008, 0x8e00, 0x0000 ; 0x0a
  dw exception11, 0x0008, 0x8e00, 0x0000 ; 0x0b
  dw exception12, 0x0008, 0x8e00, 0x0000 ; 0x0c
  dw exception13, 0x0008, 0x8e00, 0x0000 ; 0x0d
  dw exception14, 0x0008, 0x8e00, 0x0000 ; 0x0e
  dw exception15, 0x0008, 0x8e00, 0x0000 ; 0x0f
  irq0: ; 0x10
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq1: ; 0x11
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq2: ; 0x12
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq3: ; 0x13
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq4: ; 0x14
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq5: ; 0x15
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq6: ; 0x16
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq7: ; 0x17
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq8: ; 0x18
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq9: ; 0x19
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq10: ; 0x1a
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq11: ; 0x1b
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq12: ; 0x1c
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq13: ; 0x1d
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq14: ; 0x1e
    dw unhand, 0x0008, 0x8e00, 0x0000
  irq15: ; 0x1f
    dw unhand, 0x0008, 0x8e00, 0x0000
; 0x20 - 0xff
    dw int20, 0x0008, 0x8e00, 0x0000
idtend:
times 510-($-$$) db 0
dw 0xaa55

RE:interrupts again

Posted: Thu Jun 27, 2002 11:00 pm
by JavaMan
I found two "errors" but the problem remain:

1. mov sp, 0x7c00 --> mov esp, 0x7c00

2. mov cx, 80*25 --> mov ecx, 80*25

bye,
jman

RE:interrupts again

Posted: Thu Jun 27, 2002 11:00 pm
by carbonBased
You should load your segment registers with valid pmode descriptors after the CR0 step, but _before_ your far jump.

ie:

     mov eax, cr0
     or al, 1
     mov cr0, eax
     mov ax, 0x0010
     mov ds, ax
     mov es, ax
     mov fs, ax
     mov gs, ax
     mov ss, ax
     mov sp, 0x7c00
     jmp 0x0008:pm_start
[bits 32]
pm_start:
     sti

That should take care of the triple fault.
Jeff

RE:interrupts again

Posted: Fri Jun 28, 2002 11:00 pm
by JavaMan
I have worked very hard... try this:

I have built it with NASMW 0.98.08...


LINEAR_OFFSET equ 0x7c00

[org 0x0]
[bits 16]
    CLI
    
    jmp WORD 0x7c0:GO
    GO:
    
    mov ax, cs ;don't remove!
    mov ds, ax ;very important
    
    jmp short add_IRQ
    add_IRQ_BACK: ;return point
    
    lgdt [gdtr]
    lidt [idtr]
    
    mov eax, cr0
    or al, 1
    mov cr0, eax
    
    jmp DWORD CODE:pm_start
    

;
;"add_IRQ" adds IRQ handlers to IDT and "int 0x20 :-)"
;

add_IRQ: ; it uses "dw unhand, CODE, 0x8e00, 0x0000"
  
    mov BX, IRQ
    
    mov CX, 16 ;16 IRQ
    
.next:    
    mov [bx], WORD unhand
    inc bx
    inc bx
    
    mov [bx], WORD CODE
    inc bx
    inc bx
    
    mov [bx], WORD 0x8e00
    inc bx
    inc bx
    
    mov [bx], WORD 0x0000
    inc bx
    inc bx
    
loop .next

    mov [bx], WORD int20 ; INT 0x20 :-)
    inc bx
    inc bx
    
    mov [bx], WORD CODE
    inc bx
    inc bx
    
    mov [bx], WORD 0x8e00
    inc bx
    inc bx

    mov [bx], WORD 0x0000
    inc bx
    inc bx

    
    add WORD [idtr], 16*8 + 8 ; write true size...
    
    jmp short add_IRQ_BACK ;return
    

[bits 32]
pm_start:
    mov ax, LINEAR
    mov fs, ax
    mov gs, ax

    mov ax, DATA
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov ESP, 0x4000 ;stack size = 0x4000 - 512
    
    STI
    
    mov ECX, 80*25
    mov ebx, 0xb8000
        
clear_screen:
    mov [gs:ebx], word 0x0720
    inc ebx
    inc ebx
    loop clear_screen

    int 0x20
    jmp $


exception0:
    mov [0xb8000], byte '0'
    iret

exception1:
    mov [0xb8002], byte '1'
    iret

exception2:
    mov [0xb8004], byte '2'
    iret

exception3:
    mov [0xb8006], byte '3'
    iret

exception4:
    mov [0xb8008], byte '4'
    iret

exception5:
    mov [0xb800a], byte '5'
    iret

exception6:
    mov [0xb800c], byte '6'
    iret

exception7:
    mov [0xb800e], byte '7'
    iret

exception8:
    mov [0xb8010], byte '8'
    iret

exception9:
    mov [0xb8012], byte '9'
    iret

exception10:
    mov [0xb8014], byte 'a'
    iret

exception11:
    mov [0xb8016], byte 'b'
    iret

exception12:
    mov [0xb8018], byte 'c'
    iret

exception13:
    mov [0xb801a], byte 'd'
    iret

exception14:
    mov [0xb801c], byte 'e'
    iret

exception15:
    mov [0xb801e], byte 'f'
    iret

unhand:
    iret

int20:
    mov [gs:0xb8020], byte ':' ;INT 0x20 is very happy
    mov [gs:0xb8022], byte '-' ;:-)
    mov [gs:0xb8024], byte ')'
    iret

gdtr:
    dw gdtend - gdt - 1
    dd gdt + LINEAR_OFFSET

idtr:
    dw idtend - idt - 1 ; see "add_IRQ..."
    dd idt + LINEAR_OFFSET

gdt:
  NULL equ $-gdt
    dd 0x00000000, 0x00000000
    
  CODE equ $-gdt
    dw 0xFFFF
    dw LINEAR_OFFSET ;base
    db 0x00
    db 0x9A
    db 0xCF
    db 0x00
    
  DATA equ $-gdt    
    dw 0xFFFF
    dw LINEAR_OFFSET ;base
    db 0
    db 0x92
    db 0xCF
    db 0
    
  LINEAR equ $-gdt
    dw 0xFFFF
    dw 0 ;base = 0
    db 0
    db 0x92
    db 0xCF
    db 0

gdtend:

idt:
  dw exception0, CODE, 0x8e00, 0x0000  ; 0x00
  dw exception1, CODE, 0x8e00, 0x0000  ; 0x01
  dw exception2, CODE, 0x8e00, 0x0000  ; 0x02
  dw exception3, CODE, 0x8e00, 0x0000  ; 0x03
  dw exception4, CODE, 0x8e00, 0x0000  ; 0x04
  dw exception5, CODE, 0x8e00, 0x0000  ; 0x05
  dw exception6, CODE, 0x8e00, 0x0000  ; 0x06
  dw exception7, CODE, 0x8e00, 0x0000  ; 0x07
  dw exception8, CODE, 0x8e00, 0x0000  ; 0x08
  dw exception9, CODE, 0x8e00, 0x0000  ; 0x09
  dw exception10, CODE, 0x8e00, 0x0000 ; 0x0a
  dw exception11, CODE, 0x8e00, 0x0000 ; 0x0b
  dw exception12, CODE, 0x8e00, 0x0000 ; 0x0c
  dw exception13, CODE, 0x8e00, 0x0000 ; 0x0d
  dw exception14, CODE, 0x8e00, 0x0000 ; 0x0e
  dw exception15, CODE, 0x8e00, 0x0000 ; 0x0f
  
IRQ: ; created at run-time by "add_IRQ"

idtend:


times 510-($-$$) db 0
dw 0xAA55


Comment (in Italian): questo codice è perfetto!! :-)

RE:interrupts again

Posted: Fri Jun 28, 2002 11:00 pm
by Stefan
Thanks! This code realy works :) ...
PS: nice italian speach!

RE:interrupts again - sorry

Posted: Fri Jun 28, 2002 11:00 pm
by JavaMan
Sorry, my code don't work like I want...

I have forgotten to use the "GS" register in these handlers:

exception0:
    mov [gs:0xb8000], byte '0'
    iret

exception1:
    mov [gs:0xb8002], byte '1'
    iret

...
...

exception15:
    mov [gs:0xb801e], byte 'f'
    iret


so exception 8 remain! ;-(


All new code:

LINEAR_OFFSET equ 0x7c00

[org 0x0]
[bits 16]
    CLI
    
    jmp WORD 0x7c0:GO
    GO:
    
    mov ax, cs ;don't remove!
    mov ds, ax ;very important
    
    jmp short add_IRQ
    add_IRQ_BACK: ;return point
    
    lgdt [gdtr]
    lidt [idtr]
    
    mov eax, cr0
    or al, 1
    mov cr0, eax
    
    jmp DWORD CODE:pm_start
    

;
;"add_IRQ" adds IRQ handlers to IDT and "int 0x20 :-)"
;

add_IRQ: ; it uses "dw unhand, CODE, 0x8e00, 0x0000"
  
    mov BX, IRQ
    
    mov CX, 16 ;16 IRQ
    
.next:    
    mov [bx], WORD unhand
    inc bx
    inc bx
    
    mov [bx], WORD CODE
    inc bx
    inc bx
    
    mov [bx], WORD 0x8e00
    inc bx
    inc bx
    
    mov [bx], WORD 0x0000
    inc bx
    inc bx
    
loop .next

    mov [bx], WORD int20 ; INT 0x20 :-)
    inc bx
    inc bx
    
    mov [bx], WORD CODE
    inc bx
    inc bx
    
    mov [bx], WORD 0x8e00
    inc bx
    inc bx

    mov [bx], WORD 0x0000
    inc bx
    inc bx

    
    add WORD [idtr], 16*8 + 8 ; write true size...
    
    jmp short add_IRQ_BACK ;return
    

[bits 32]
pm_start:
    
    mov ax, FLAT
    mov fs, ax
    mov gs, ax

    mov ax, DATA
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov ESP, 0x4000 ;stack size = 0x4000 - 512

    
    mov ECX, 80*25
    mov ebx, 0xb8000
        
clear_screen:
    mov [gs:ebx], word 0x0720
    inc ebx
    inc ebx
    loop clear_screen
    
    STI
    
    ;mov bl, 0 ;Test for div by 0
    ;mov ax, 3
    ;div bl

    int 0x20
    jmp $


exception0:
    mov [gs:0xb8000], byte '0'
    iret

exception1:
    mov [gs:0xb8002], byte '1'
    iret

exception2:
    mov [gs:0xb8004], byte '2'
    iret

exception3:
    mov [gs:0xb8006], byte '3'
    iret

exception4:
    mov [gs:0xb8008], byte '4'
    iret

exception5:
    mov [gs:0xb800a], byte '5'
    iret

exception6:
    mov [gs:0xb800c], byte '6'
    iret

exception7:
    mov [gs:0xb800e], byte '7'
    iret

exception8:
    mov [gs:0xb8010], byte '8'
    iret

exception9:
    mov [gs:0xb8012], byte '9'
    iret

exception10:
    mov [gs:0xb8014], byte 'a'
    iret

exception11:
    mov [gs:0xb8016], byte 'b'
    iret

exception12:
    mov [gs:0xb8018], byte 'c'
    iret

exception13:
    mov [gs:0xb801a], byte 'd'
    iret

exception14:
    mov [gs:0xb801c], byte 'e'
    iret

exception15:
    mov [gs:0xb801e], byte 'f'
    iret

unhand:
    iret

int20:
    mov [gs:0xb8020], byte 'O' ;INT 0x20 is very happy
    mov [gs:0xb8022], byte 'k' ;:-)
    iret

gdtr:
    dw gdtend - gdt - 1
    dd gdt + LINEAR_OFFSET

idtr:
    dw idtend - idt - 1 ; see "add_IRQ..."
    dd idt + LINEAR_OFFSET

gdt:
  NULL equ $-gdt
    dd 0x00000000, 0x00000000
    
  CODE equ $-gdt
    dw 0xFFFF
    dw LINEAR_OFFSET ;base
    db 0x00
    db 0x9A
    db 0xCF
    db 0x00
    
  DATA equ $-gdt    
    dw 0xFFFF
    dw LINEAR_OFFSET ;base
    db 0
    db 0x92
    db 0xCF
    db 0
    
  FLAT equ $-gdt
    dw 0xFFFF
    dw 0 ;base = 0
    db 0
    db 0x92
    db 0xCF
    db 0

gdtend:

idt:
  dw exception0, CODE, 0x8e00, 0x0000  ; 0x00
  dw exception1, CODE, 0x8e00, 0x0000  ; 0x01
  dw exception2, CODE, 0x8e00, 0x0000  ; 0x02
  dw exception3, CODE, 0x8e00, 0x0000  ; 0x03
  dw exception4, CODE, 0x8e00, 0x0000  ; 0x04
  dw exception5, CODE, 0x8e00, 0x0000  ; 0x05
  dw exception6, CODE, 0x8e00, 0x0000  ; 0x06
  dw exception7, CODE, 0x8e00, 0x0000  ; 0x07
  dw exception8, CODE, 0x8e00, 0x0000  ; 0x08
  dw exception9, CODE, 0x8e00, 0x0000  ; 0x09
  dw exception10, CODE, 0x8e00, 0x0000 ; 0x0a
  dw exception11, CODE, 0x8e00, 0x0000 ; 0x0b
  dw exception12, CODE, 0x8e00, 0x0000 ; 0x0c
  dw exception13, CODE, 0x8e00, 0x0000 ; 0x0d
  dw exception14, CODE, 0x8e00, 0x0000 ; 0x0e
  dw exception15, CODE, 0x8e00, 0x0000 ; 0x0f
  
IRQ: ; created at run-time by "add_IRQ"

idtend:


times 510-($-$$) db 0
dw 0xAA55



Tomorrow I will go to Sardinia for 3 weeks...
BYE