Problems with IDT/ISR/IRQ and VM86

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
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Problems with IDT/ISR/IRQ and VM86

Post by kenneth_phough »

I am also working on writing my IDT/ISR for my OS. I wish to write my IDT in asm instead of C but I am having trouble with the base address for my IDT entry. My ISR is also written in asm and the handler is written in C. My problem is how can I get the base address of the 17 isr (exception 0-16) to put in to my IDT entry?

Also my understading on IDTs is still vague. Please correct me if I am wrong: which handler to use for each exceptions and irqs are set through the IDT by letting the PIC know the address of each handler.


My other problem is I want my OS to be able to swith the vga mode from text to graphical but I would need to call BIOS interrupt 0x10 which can only be done in real mode. Therefore I would need to use virtual 8086 mode. By any chance is there an alternative was to change vga modes in protected mode?

Thanks,
Kenneth
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post by JAAman »

I am also working on writing my IDT/ISR for my OS. I wish to write my IDT in asm instead of C but I am having trouble with the base address for my IDT entry. My ISR is also written in asm and the handler is written in C. My problem is how can I get the base address of the 17 isr (exception 0-16) to put in to my IDT entry?
(iirc)you cant without hard-coding the addresses (because the addresses are split into high and low halves, most linkers cannot handle this) -- you must do it at runtime -- have your code place the appropriate values in the locations
Also my understading on IDTs is still vague. Please correct me if I am wrong: which handler to use for each exceptions and irqs are set through the IDT by letting the PIC know the address of each handler.
the PIC doesnt know or care where the address of the handler is -- all it does is tell the CPU that there is a hard-int

the CPU then takes the interupt number off the bus (provided by the PIC or APIC), or an internal exception, or a soft int number (all 3 are handled the same way) and uses that as an index into the IDT, and fetches the handler address, and then enters it (as discribed in section 5.12 volume 3)
My other problem is I want my OS to be able to swith the vga mode from text to graphical but I would need to call BIOS interrupt 0x10 which can only be done in real mode. Therefore I would need to use virtual 8086 mode. By any chance is there an alternative was to change vga modes in protected mode?
if you stick with true VGA modes (such as 12 or 13 -- 640x480x16/300x200x256), yes this is quite easy -- just google for vga docs, should find -- i think its called "vgadoc2b" or something like that the ports used by all VGA compatable cards are standard and very well documented (this is how win3.1/95/98 does "safe mode")



ps -- sorry for the late reply, i was almost finnished typing this when i hurt my arm -- now im typing with one hand -- and its not even my right hand :(
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Post by kenneth_phough »

I'm sorry about your arm. :sad: I hope it's better now.

Thank you very much for the info. :wink: I finally got my IDT to work but now I have a new problem. When ever the timer fires, it causes a general protection fault. I checked the Intel Manual Vol 3a for a descreption on what causes a #GP but I couldn't find any piece of code in my OS that is causing the GP. So I decided to put for( ; ; ); loops here and there to figure out where the problem is and i found out that it happens when the iret opcode is executed. So I looked up the iret opcode in the Intel Manual Vol 2a and it said that the only way to cause a GP is by returning to the wrong/null stack segment. But my stack segment is always set to 0x10 (kernel data).
I have to go soon but I'll post my code as soon as I get back.

I'll check out the vga stuff ASAP! I really want to write my own GUI for my OS :D .

Thank you very much!
Kenneth
Last edited by kenneth_phough on Thu Aug 17, 2006 7:13 am, edited 2 times in total.
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Post by kenneth_phough »

I'm back 8) .
The following are the source codes for calling interrupt handlers:

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                  irq.asm                   ;;
;;                Version 0.0.3                ;;
;;     Copyright (c) 2006 Kenneth P. Hough    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[BITS 32]

global irq0, irq1, irq2, irq3, irq4, irq5, irq6, irq7, irq8, irq9, irq10, irq11, irq12, irq13, irq14, irq15
extern irq_hndlr_0, irq_hndlr_1, irq_hndlr_2, irq_hndlr_3, irq_hndlr_4, irq_hndlr_5, irq_hndlr_6, irq_hndlr_7, irq_hndlr_8, irq_hndlr_9, irq_hndlr_10, irq_hndlr_11, irq_hndlr_12, irq_hndlr_13, irq_hndlr_14, irq_hndlr_15

irq0:
cli

push byte 0
push byte 32

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_0

pop ds
pop es
pop fs
pop gs
popa
iret

irq1:
cli

push byte 0
push byte 33

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_1

pop ds
pop es
pop fs
pop gs
popa
iret

irq2:
cli

push byte 0
push byte 34

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_2

pop ds
pop es
pop fs
pop gs
popa
iret

irq3:
cli

push byte 0
push byte 35

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_3

pop ds
pop es
pop fs
pop gs
popa
iret

irq4:
cli

push byte 0
push byte 36

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_4

pop ds
pop es
pop fs
pop gs
popa
iret

irq5:
cli

push byte 0
push byte 37

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_5

pop ds
pop es
pop fs
pop gs
popa
iret

irq6:
cli

push byte 0
push byte 38

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_6

pop ds
pop es
pop fs
pop gs
popa
iret

irq7:
cli

push byte 0
push byte 39

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_7

pop ds
pop es
pop fs
pop gs
popa
iret

irq8:
cli

push byte 0
push byte 40

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_8

pop ds
pop es
pop fs
pop gs
popa
iret

irq9:
cli

push byte 0
push byte 41

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_9

pop ds
pop es
pop fs
pop gs
popa
iret

irq10:
cli

push byte 0
push byte 42

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_10

pop ds
pop es
pop fs
pop gs
popa
iret

irq11:
cli

push byte 0
push byte 43

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_11

pop ds
pop es
pop fs
pop gs
popa
iret

irq12:
cli

push byte 0
push byte 44

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_12

pop ds
pop es
pop fs
pop gs
popa
iret

irq13:
cli

push byte 0
push byte 45

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_13

pop ds
pop es
pop fs
pop gs
popa
iret

irq14:
cli

push byte 0
push byte 46

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_14

pop ds
pop es
pop fs
pop gs
popa
iret

irq15:
cli

push byte 0
push byte 47

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call irq_hndlr_15

pop ds
pop es
pop fs
pop gs
popa
iret

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                  isr.asm                   ;;
;;                Version 0.0.1                ;;
;;     Copyright (c) 2006 Kenneth P. Hough    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

[BITS 32]

global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10, isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21, isr22, isr23, isr24, isr25, isr26, isr27, isr28, isr29, isr30, isr31
extern excp_hndlr_0, excp_hndlr_1, excp_hndlr_2, excp_hndlr_3, excp_hndlr_4, excp_hndlr_5, excp_hndlr_6, excp_hndlr_7, excp_hndlr_8, excp_hndlr_9, excp_hndlr_10, excp_hndlr_11, excp_hndlr_12, excp_hndlr_13, excp_hndlr_14, excp_hndlr_15, excp_hndlr_16, excp_hndlr_17, excp_hndlr_18, excp_hndlr_19, excp_hndlr_20, excp_hndlr_21, excp_hndlr_22, excp_hndlr_23, excp_hndlr_24, excp_hndlr_25, excp_hndlr_26, excp_hndlr_27, excp_hndlr_28, excp_hndlr_29, excp_hndlr_30, excp_hndlr_31

global load_idt
extern idtp

load_idt:
lidt[idtp]
ret

isr0:
cli

push byte 0
push byte 0

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_0

pop ds
pop es
pop fs
pop gs
popa
iret

isr1:
cli

push byte 0
push byte 1

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_1

pop ds
pop es
pop fs
pop gs
popa
iret

isr2:
cli

push byte 0
push byte 2

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_2

pop ds
pop es
pop fs
pop gs
popa
iret

isr3:
cli

push byte 0
push byte 3

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_3

pop ds
pop es
pop fs
pop gs
popa
iret

isr4:
cli

push byte 0
push byte 4

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_4

pop ds
pop es
pop fs
pop gs
popa
iret

isr5:
cli

push byte 0
push byte 5

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_5

pop ds
pop es
pop fs
pop gs
popa
iret

isr6:
cli

push byte 0
push byte 6

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_6

pop ds
pop es
pop fs
pop gs
popa
iret

isr7:
cli

push byte 0
push byte 7

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_7

pop ds
pop es
pop fs
pop gs
popa
iret

isr8:
cli

push byte 0
push byte 8

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_8

pop ds
pop es
pop fs
pop gs
popa
iret

isr9:
cli

push byte 0
push byte 9

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_9

pop ds
pop es
pop fs
pop gs
popa
iret

isr10:
cli

push byte 0
push byte 10

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_10

pop ds
pop es
pop fs
pop gs
popa
iret

isr11:
cli

push byte 0
push byte 11

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_11

pop ds
pop es
pop fs
pop gs
popa
iret

isr12:
cli

push byte 0
push byte 12

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_12

pop ds
pop es
pop fs
pop gs
popa
iret

isr13:
cli

push byte 0
push byte 13

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_13

pop ds
pop es
pop fs
pop gs
popa
iret

isr14:
cli

push byte 0
push byte 14

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_14

pop ds
pop es
pop fs
pop gs
popa
iret

isr15:
cli

push byte 0
push byte 15

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_15

pop ds
pop es
pop fs
pop gs
popa
iret

isr16:
cli

push byte 0
push byte 16

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_16

pop ds
pop es
pop fs
pop gs
popa
iret

isr17:
cli

push byte 0
push byte 17

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_17

pop ds
pop es
pop fs
pop gs
popa
iret

isr18:
cli

push byte 0
push byte 18

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_18

pop ds
pop es
pop fs
pop gs
popa
iret

isr19:
cli

push byte 0
push byte 19

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_19

pop ds
pop es
pop fs
pop gs
popa
iret

isr20:
cli

push byte 0
push byte 20

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_20

pop ds
pop es
pop fs
pop gs
popa
iret

isr21:
cli

push byte 0
push byte 21

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_21

pop ds
pop es
pop fs
pop gs
popa
iret

isr22:
cli

push byte 0
push byte 22

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_22

pop ds
pop es
pop fs
pop gs
popa
iret

isr23:
cli

push byte 0
push byte 23

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_23

pop ds
pop es
pop fs
pop gs
popa
iret

isr24:
cli

push byte 0
push byte 24

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_24

pop ds
pop es
pop fs
pop gs
popa
iret

isr25:
cli

push byte 0
push byte 25

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_25

pop ds
pop es
pop fs
pop gs
popa
iret

isr26:
cli

push byte 0
push byte 26

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_26

pop ds
pop es
pop fs
pop gs
popa
iret

isr27:
cli

push byte 0
push byte 27

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_27

pop ds
pop es
pop fs
pop gs
popa
iret

isr28:
cli

push byte 0
push byte 28

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_28

pop ds
pop es
pop fs
pop gs
popa
iret

isr29:
cli

push byte 0
push byte 29

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_29

pop ds
pop es
pop fs
pop gs
popa
iret

isr30:
cli

push byte 0
push byte 30

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_30

pop ds
pop es
pop fs
pop gs
popa
iret

isr31:
cli

push byte 0
push byte 31

pusha
push gs
push fs
push es
push ds

mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call excp_hndlr_31

pop ds
pop es
pop fs
pop gs
popa
iret
dave
Member
Member
Posts: 42
Joined: Sat Jul 09, 2005 11:00 pm

Post by dave »

You are pushing two bytes to the stack at the beginning of you interrupt handlers which do not appear to be removed from the stack (The code you posted does not show it being removed from the stack).

Code: Select all

irq0: 
cli 

push byte 0    <-- these bytes are not remove from the stack
push byte 32  <-- 

pusha 
push gs 
push fs 
push es 
push ds 

mov ax, 0x10 
mov ds, ax 
mov es, ax 
mov fs, ax 
mov gs, ax 

call irq_hndlr_0 

pop ds 
pop es 
pop fs 
pop gs 
popa 

     <-- not popping extra bytes from stack
     <-- this will cause the top of the stack to have an incorrect return
     <-- address for iret instruction
iret 
Again, I am assuming you do not pop this data off anywhere else in your code. If you are not popping this data off then iret is getting a corrupted return address from the top of the stack.

dave
User avatar
kenneth_phough
Member
Member
Posts: 106
Joined: Sun Sep 18, 2005 11:00 pm
Location: Williamstown, MA; Worcester, MA; Yokohama, Japan
Contact:

Post by kenneth_phough »

Totally forgot! :oops:
Been up for a long time...
Finally got it to work. Thanks.
I also noticed I was missing out on quite a lot of stuff such as sending a EOI to the slave controller if the IRQ is greater than 7 and to send an EOI to the master interrupt controller after handling the interrupt.

Thanks,
Kenneth
Post Reply