Page 1 of 1

Interrupt Troubles

Posted: Sat Jan 28, 2012 2:06 pm
by Unkn0wn1
Hi,

I am trying to set up some basic interrupt handlers (Real mode, assembler),
using the following code

Code: Select all

	hlt
	iret

idt_data:
   dw (base_addr + isr0 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16

   dw (base_addr + isr1 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16

   dw (base_addr + isr2 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16

   dw (base_addr + isr3 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16

   dw (base_addr + isr4 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16



loadints:
   cli       
   pusha         
   lidt    [load]                             
   popa
    sti
   ret     

end_of_idt:
load: 
   dw end_of_idt - idt_data - 1    
   dd idt_data


error db "FIND has suffered something painful and has to quit :(", 0

When I run it in Bochs, after the kernel calls

Code: Select all

 int 01h
the following occurs, and keyboard input fails -- Yeah, I did cli and sti:

Code: Select all

Plex86/Bochs VGABios (PCI) 0.7a 30 Oct 2011
This VGA/VBE Bios is released under the GNU LGPL

Please visit :
 . http://bochs.sourceforge.net
 . http://www.nongnu.org/vgabios

Bochs VBE Display Adapter enabled

Bochs BIOS - build: 11/24/11
$Revision: 10789 $ $Date: 2011-11-24 17:03:51 +0100 (Do, 24. Nov 2011) $
Options: apmbios pcibios pnpbios eltorito rombios32


Press F12 for boot menu.

Booting from Floppy...

Loading Boot Image
..............
..................
............
Welcome to FIND (C) 2011 Ben Jackson. Enter 'help' for a lis of commands
ß
The code that sets up interrupts, just before the main shell but after the intro is this:

Code: Select all

	call loadints
        int 01h
Oh, by the way, the Bochs log is going like this, ad infinitum

[CPU0 ] prefetch: EIP [00010000] > CS.limit [0000ffff]
[CPU0 ] interrupt(real mode) vector > idtr.limit
:

Re: Interrupt Troubles

Posted: Sat Jan 28, 2012 2:26 pm
by bluemoon
Unkn0wn1 wrote:I am trying to set up some basic interrupt handlers (Real mode, assembler),
using the following code

Code: Select all

	hlt
	iret

idt_data:
   dw (base_addr + isr0 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16
<snip>
loadints:
   cli       
   pusha         
   lidt    [load]                             
   popa
    sti
   ret     
In real mode the interrupt vectors are fixed at 0000:0000. LIDT loads the table into IDTR which are ignored in real mode.

From IA manual:
They are commonly executed in real-address mode to allow processor initialization prior to switching to protected mode.

Re: Interrupt Troubles

Posted: Sat Jan 28, 2012 2:36 pm
by turdus
Unkn0wn1 wrote:

Code: Select all

idt_data:
   dw (base_addr + isr0 - $$) & 0xFFFF
   dw 0x8
   db 0x0
   db 0x8E
   dw (base_addr + handler - $$) >> 16
bluemoon wrote: In real mode the interrupt vectors are fixed at 0000:0000. LIDT loads the table into IDTR which are ignored in real mode.
True, furthermore in real mode there're no descriptors in table at all. IVT contains only seg:offs pairs.

Re: Interrupt Troubles

Posted: Sat Jan 28, 2012 2:41 pm
by Unkn0wn1
OK, so how would I declare an entry and load it?

Oh, and also how would I get the S:O of my handlers? (My assembler is NASM, if it helps)

Re: Interrupt Troubles

Posted: Sun Jan 29, 2012 3:21 pm
by Unkn0wn1
OK, but how do I load the handler into the vector table without FUBARing it?

Almost thinking of doing a JMP-based syscall interface

Re: Interrupt Troubles

Posted: Mon Jan 30, 2012 12:25 pm
by Unkn0wn1
Cracked it! my install routine is as follows, in the hope that it benefits someone, somewhere who is having/will have the same problem as I am. It looks like this

Code: Select all

push word 0
pop ds
mov [4 * SYSCALL_INTERRUPT], word syscallHandler
mov [4 * SYSCALL_INTERRUPT + 2], cs
push cs
pop ds
Sets DS to zero, moves the address of a procedure called syscallHandler to the RAM at 4 times the number of the int (Defined in a seperate include file) -- S:O addresses are 4 bytes, that's the first 2. The offset is set as cs, and then DS is set to CS

Re: Interrupt Troubles

Posted: Mon Jan 30, 2012 12:33 pm
by bluemoon
Uncommented code with magic numbers would not benefit people.

Only the two mov are revalent for patching IVT.

The push cs / pop ds assume you want to set DS=CS, which may not be necessary in some situation. And then you need CLI somewhere before doing the patch.

EDIT: I noticed you added description.

The push cs / pop ds is a bit awkward, you may do this if you really need to preserve DS

Code: Select all

push ds 		; backup DS
push word 0
pop ds		; DS = 0
mov word [4 * SYSCALL_INTERRUPT], syscallHandler
mov word [4 * SYSCALL_INTERRUPT + 2], cs
			; [0:INTx4] -> FAR CS:Handler
pop ds		; restore DS

Re: Interrupt Troubles

Posted: Mon Jan 30, 2012 3:07 pm
by Unkn0wn1
Fair enough, just has the SYSCALL_INTERRUPT so that it's easier to set different interrupts for different reasons (I.E. Unixy systems use int 80h, so it's just easier to make portable code incase I feel like doing a unixy system some time)