idt troubles....
Posted: Tue Jul 14, 2009 1:59 am
This is frustrating as hell... Here's what I do:
(Please assume all my screen printing functions work; they do.)
1.) Set the screen colors to one color scheme.
2.) Set up IDT entry for interrupt 0
3.) Load the IDT descriptor with lidt
4.) Now I call int 0x00, but the ISR is not executed (it outputs a string that I'd see)
5.) Now I change the screen colors to another color scheme. This is never executed. The old color scheme is still in place. Int 0 never returned.
Again, assume the screen printing functions work such as changing the screen color (k_set_screen_colors) and printing a string (k_print_string_in_bounds) because they've been tested individually and work fine. The problem is setting up the IDT entry 0 to point to my ISR...
Here is the code the events above
And here is the function that sets up an IDT entry (I suspect the problem is here but I cannot find it...):
Here is my ISR
Finally, here is my IDT:
I realize that that's a ton, but I'm hoping someone might take the time to possibly skim through that and find and major flaws because I'm at a complete deadlock with this faulty code. I've been looking for an error for several hours. Your help is very much appreciated... I hope it saves me from this frustrating insanity,
Brodeur235
(Please assume all my screen printing functions work; they do.)
1.) Set the screen colors to one color scheme.
2.) Set up IDT entry for interrupt 0
3.) Load the IDT descriptor with lidt
4.) Now I call int 0x00, but the ISR is not executed (it outputs a string that I'd see)
5.) Now I change the screen colors to another color scheme. This is never executed. The old color scheme is still in place. Int 0 never returned.
Again, assume the screen printing functions work such as changing the screen color (k_set_screen_colors) and printing a string (k_print_string_in_bounds) because they've been tested individually and work fine. The problem is setting up the IDT entry 0 to point to my ISR...
Here is the code the events above
Code: Select all
; setup screen colors
xor eax,eax
mov al,LIGHT_GREY
shl al,4
or al,BLACK
push eax
call k_set_screen_colors
add esp,4
call k_clear_screen
; setup an ISR:
; push DPL param
xor eax,eax
push eax
; push selector param
mov eax,0x00000008
push eax
; push offset of isr
mov eax,((ISR_0-k_main)+KERNEL_OFFSET) ;This IS the address of the ISR. This is NOT the problem.
push eax
; push interrupt #
xor eax,eax
push eax
call k_install_isr
add esp,0x00000010
; load the idt
lidt [idt_descriptor]
; call an interrupt
int 0x00
; change screen colors
xor eax,eax
mov al,BLUE
shl al,4
or al,LIGHT_CYAN
push eax
call k_set_screen_colors
add esp,4
Code: Select all
; @param1 interrupt # (0-255)
; @param2 offset of ISR
; @param3 selecter (in GDT) for ISR
; @param4 DPL (ISR ring level)
%define NUM DWORD [ebp-16]
%define OFF DWORD [ebp-12]
%define SEL DWORD [ebp-8]
%define DPL DWORD [ebp-4]
k_install_isr:
; setup stack frame
push ebp
mov ebp,esp
; create space for local vars
sub esp,0x00000010
; get interrupt number
mov eax,DWORD [ebp+8]
mov NUM,eax
; get offset
mov eax,DWORD [ebp+12]
mov OFF,eax
; get selector
mov eax,DWORD [ebp+16]
mov SEL,eax
; get DPL
mov eax,DWORD [ebp+20]
mov DPL,eax
; calculate base address for interrupt entry
xor eax,eax
add eax,NUM
imul eax,0x00000008
add eax,idt_entries
; put the lower word of the offset at the address
xor ebx,ebx
mov ebx,OFF
mov WORD [ds:eax],bx
add eax,0x00000002
; put the selector at updated address
xor ebx,ebx
mov ebx,SEL
mov WORD [ds:eax],bx
add eax,0x00000002
; put an empty byte at updated address
xor ebx,ebx
mov BYTE [ds:eax],bl
inc eax
; put the access byte at updated address
xor ebx,ebx
mov ebx,DPL
shl bl,0x05
or bl,10000000b ; bit mask turns on "present" bit
or bl,00001110b ; bit mask makes int a 32 bit gate
mov BYTE [ds:eax],bl
inc eax
; put the upper word of the offset at the updated address
xor ebx,ebx
mov ebx,OFF
shr ebx,0x00000010
mov WORD [ds:eax],bx
; clean up stack frame
mov esp,ebp
pop ebp
ret
Code: Select all
ISR_0:
; save registers
pusha
push ds
push es
push fs
push gs
; setup stack frame
push ebp
mov ebp,esp
; print a string
push DWORD 25
push DWORD 80
push DWORD 1
push DWORD 1
push DWORD 1
push DWORD 1
xor eax,eax
mov eax,((isr0_exec-k_main)+KERNEL_OFFSET)
push eax
call k_put_string_in_bounds
add esp,0x0000001C
; clean up stack frame
mov esp,ebp
pop ebp
; load registers
pop gs
pop fs
pop es
pop ds
popa
iret
Code: Select all
idt_entries:
; insert 256 zeroed out interrupt entries
%rep 0x00000100
dd 0x00000000
dd 0x00000000
%endrep
idt_descriptor:
; 2 byte size
dw (idt_descriptor-idt_entries-1)
; 4 byte offset
dd idt_entries
Brodeur235