still can't get this bedamned IDTR to work!
Posted: Thu Mar 20, 2003 8:00 pm
I dunno if I'm missing something or what...I mean I guess I am. I've been working on this for about 2 days, and still haven't gotten it to fire an interrupt.
I can guarantee that syntax is fine, there are no gcc/nasm/ld errors. I can guarantee that the functions int0-int49 actually do exist. Finally, I can guarantee that the interrupts are enabled. Anyway, here's the code:
A very heavily modded and commented Chris Giese kernel start. I guess I just must be an idiot or something. OH yeah, and I'm pretty sure it's not the fact that I tapered the IDTR down to 49 entries because 256 did the same thing... In fact, I'm probably safe in saying that the C code with this is fine, as it worked with the original Chris Giese kernelstart (all it does is remap the PIC, enable interrupts and call the interrupt...along with defining all of the functions referenced by this asm code)
I can guarantee that syntax is fine, there are no gcc/nasm/ld errors. I can guarantee that the functions int0-int49 actually do exist. Finally, I can guarantee that the interrupts are enabled. Anyway, here's the code:
Code: Select all
[BITS 32]
[GLOBAL start]
[EXTERN _osmain]
[EXTERN _ASMdebug]
;we are currently @ 1MB physical
start:
???lgdt [gdtr] ???;load new GDT (after bootsector did its thing)
???mov ax,DATASEL???;all registers but CS are set to data
???mov ds,ax
???mov es,ax
???mov ss,ax
???mov fs,ax
???mov gs,ax
???jmp CODESEL:startagain ;cs is set to code through a jump to startagain.
???
startagain:
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This is a beautiful chunk of code that automatically sets the offsets
;for the interrupts, this is why the the intr calls have to be in order,
;uninterrupted and why they all have to be there (or things get misplaced)
???mov ecx,(idt_end - idt) >> 3 ???;ECX = number of times to loop (number of isr stubs)
???mov edi,idt?????????;EDI = beginning of idt table
???mov esi,isr0?????????;ESI = beginning of isr stubs
do_idt:????????????;LOOP
???mov eax,esi?????????; EAX = address of current isr stub
???mov [edi],ax?????????; 1st entry = low 16bits of EAX (isr address)
???shr eax,16?????????; EAX = EAX's high 16 bits
???mov [edi + 6],ax??????; 4th entry = high 16 bits of EAX (isr address)
???add edi,8?????????; increment to the next idtr entry (8 bytes per entry)
???add esi,(isr1 - isr0)??????; increment to the next isr entry (isr1-isr0 bytes per entry)
???loop do_idt?????????;GOTO LOOP
???
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;Load the IDTR, get into the C main code, if that code returns
;(which it never should) then halt the CPU
???lidt [idt_ptr]
???call _osmain
???hlt
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This macro defines an interrupt stub.
%macro INTR 1
isr%1:
???push byte 0???
???db 6Ah
???db %1
???push gs?????????; push segment registers
???push fs????????????
???push es????????????
???push ds????????????
???pusha?????????; push GP registers
???mov ax,DATASEL??????; put known-good values...
???mov ds,eax??????; ...in segment registers
???mov es,eax??????
???mov fs,eax??????
???mov gs,eax??????
???call _int%1???
?????????
???popa?????????; pop GP registers
???pop ds?????????; pop segment registers
???pop es
???pop fs
???pop gs
???iret?????????;return to the previous C function, just like everything
????????????;was before the interrupt (iret = interrupt return)
%endmacro????????????
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This repetition defines all of the C funtions that handle interrupts
%macro IMPORTINT 1
???[EXTERN _int%1]
%endmacro
%assign i 0
%rep (49)???
???IMPORTINT i???
%assign i (i + 1)
%endrep
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;This repetition defines the stubs for 49 interrupts. the idtr is capable
;of holding 256 but the last 207 are undefined.
%assign i 0
%rep (49)???
???INTR i
%assign i (i + 1)
%endrep
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;GDT TABLE information
gdt:
dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; type
db 0 ; limit 19:16, flags
db 0 ; base 31:24
dd 0 ;this is the same as above, still just 8 bits of blanks
dd 0
DATASEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 92h ; present, ring 0, data, expand-up, writable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
CODESEL equ $-gdt
dw 0FFFFh
dw 0
db 0
db 9Ah ; present,ring 0,code,non-conforming,readable
db 0CFh ; page-granular (4 gig limit), 32-bit
db 0
gdtend:
gdtr:
dw gdtend - gdt - 1
dd gdt
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
;IDT INFORMATION
idt:
%rep 49
dw 0 ;0
dw DATASEL ;2
dw 0x8E00 ;4
dw 0 ;6
%endrep
idt_end:
idt_ptr:
dw idt_end - idt - 1
dd idt