still can't get this bedamned IDTR to work!

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
stonedzealot

still can't get this bedamned IDTR to work!

Post by stonedzealot »

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:

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
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)
Chris Giese

Re:still can't get this bedamned IDTR to work!

Post by Chris Giese »

wangpeng wrote:

Code: Select all

%rep 49     
   dw 0      ;0
   dw DATASEL   ;2
   dw 0x8E00    ;4   
   dw 0      ;6
%endrep   
Ooooh, missed it by one byte :)

Change the DATASEL to CODESEL and it should work.
stonedzealot

Re:still can't get this bedamned IDTR to work!

Post by stonedzealot »

Ah. Duh. You store interrupt handlers as code...not data. <wap> I can't believe I didn't think of that. Thanks alot. BTW, I learned so much from reading your code. It was excellent. Thanks alot! :)

--=BTW, the masterful Chris Giese was correct, this works now.=--
Post Reply