Page 1 of 1
How to set up an IDT
Posted: Sat Jan 27, 2007 1:15 am
by XCHG
It has been a few days since I’ve started searching for a working example of an IDT and unfortunately I haven’t yet been able to find one written in NASM (with its bloated syntax). I have only set up my GDT and switched to PM with a very small kernel which only clears the screen. I would really appreciate it if somebody could give me an example that for example sets up the IDT for INT 0x10, written in NASM. Thanks in advance guys.
Re: How to set up an IDT
Posted: Sat Jan 27, 2007 3:44 am
by Ready4Dis
XCHG wrote:It has been a few days since I’ve started searching for a working example of an IDT and unfortunately I haven’t yet been able to find one written in NASM (with its bloated syntax). I have only set up my GDT and switched to PM with a very small kernel which only clears the screen. I would really appreciate it if somebody could give me an example that for example sets up the IDT for INT 0x10, written in NASM. Thanks in advance guys.
int 0x10 in PM is not the same as int 0x10 in real mode, just to give you a heads up. You have to fill in all interrupts in pmode, you can't just call them or it will triple fault, you must initialize them before use, and give them an interrupt routine/handler. If you are looking to use int 0x10 (video interrupt in real mode), you must be in real mode (*or equivelant, ala virtual x86 mode).
Posted: Sat Jan 27, 2007 3:53 am
by Otter
The simplest way is to use a hardcoded idt, for expample:
Code: Select all
%macro idtentry 2
dw %1 & 0xFFFF ; Low-Word of Offset
dw %2 ; Code-Segment-Selector
dw 0x8e00
dw %1 >> 16
%endmacro
idt:
times 0x10 dd 0,0 ; the first 0x10 entries
idtentry __myInt10h,0x08 ; dunno what your code segment selector is, assuming 0x08
idt_end:
idtR:
dw idt_end-idt-1
dd idt
__myInt10h:
; Your code for int10h
iret
You can load this IDT by "lidt [idtR]"
Posted: Sun Jan 28, 2007 5:20 am
by XCHG
Thank you so much guys. I'm starting to *really* like this community. I appreciate it.
How to set up an IDT
Posted: Fri Feb 02, 2007 4:24 am
by XCHG
I don’t think my IDT is working correctly. Well the first problem is that NASM complains when I use &, >>, << and etc with my trap-handler’s offset. For example, this is what I had in mind which however doesn’t work:
Code: Select all
Int10Handler:
;~
IRET
; -----------------------------
ALIGN 8, NOP
IDT:
TIMES 0x10 DD 0 , 0
DW Int10Handler & 0xFFFF
DW 0x0008
DW 0x8E00
DW (Int10Handler >> 0x10) & 0xFFFF
IDT_END:
;------------------------------
IDTR:
DW (IDT_END - IDT) - 1
DD IDT
I also retrieved the offset to the “Int10Handler” procedure and created a “__WriteInt” procedure to retrieve its address manually. I then put the high and the low order words of the “Int10Handler” procedure in the corresponding descriptor but the system crashed and rebooted as soon as I enabled the interrupts. Does anybody have any idea how I can first fix the problem with NASM operators and then fix my IDT?
Posted: Fri Feb 02, 2007 6:58 am
by Otter
You cannot use operators like & and << with offsets which are not known at assemble time. If you use "nasm -fbin" they are known, but if you use elf as target they are filled in by the linker. So I'm afraid you have to set up the idt in run time ...
[edit]A simple example: (untested)
Code: Select all
IDT:
times 0x10 dd 0,0
dd Int10Handler,Int10Handler
IDT_END:
; IDT is not valid yet ... this code should correct it
setupIdt:
mov ecx,(IDT_END - IDT ) / 8
mov edx,IDT
setupIdt_loop:
cmp dword[edx],0
jz setupIdt_loopNext
mov dword[edx+2],0x8E000008
setupIdt_loopNext:
add edx,8
loop setupIdt_loop
I use a simple trick: You see the template for the idt entry, which is: "dd Int10Handler,Int10Handler" ... you can see that the lower word and the high word of the Idt10Handler are in the correct fields ... only the code segment selector 0x0008 and the 0x8e00 have to be added[/edit]
Posted: Sat Feb 03, 2007 12:32 am
by XCHG
Oh so basically I have to fill the IDT at run-time, is that close on being on the money? I should then be able to enable the interrupts with STI right? I am going to try it now. Thank you so much.
Posted: Sat Feb 03, 2007 1:15 am
by XCHG
Okay I got the IDT working but there is something that I don't understand.
I was looking to set up the IDT to use it for Traps (Software Interrupts) and without setting the Interrupt Flag, I can still use the INT instruction.
Here is how I set the IDT:
Code: Select all
Int10Handler: ; Dummy INT 0x10 Handler
MOV EBX , VIDEOSEGMENT
ADD EBX , DWORD PTR [VideoCursor]
MOV WORD PTR [EBX] , 0x0F41
IRET ; Return from the Trap
; -----------------------------
ALIGN 8, NOP ; Align the IDT on QWORD boundary
IDT: ; Beginning of the IDT
TIMES 0x10 DD 0 , 0 ; 16 empty descriptors
DW 0x0000 ; Low order Word of the handler
DW 0x0008 ; Code segment selector in GDT
DW 0x8F00 ; Trap Gate
DW 0x0000 ; High order Word of the handler
IDT_END: ; End of the IDT
;------------------------------
IDTR: ; Limits of the IDT
DW (IDT_END - IDT) - 1 ; Integer multiple of 8 minus 1
DD IDT ; Starting point of the IDT
In the kernel, I tried set the Low and the High Order Word of the Trap handler like this:
Code: Select all
%IDEFINE EMPTYSLOTCOUNT 0x10
%IDEFINE IDT_ENTRY_LEN 0x08
%IDEFINE BYTESTOSKIP (EMPTYSLOTCOUNT * IDT_ENTRY_LEN)
; ---------------------------
LEA EBX , [IDT + BYTESTOSKIP] ; EA of the last descriptor
MOV EAX , Int10Handler ; Get the offset of the handler
MOV WORD PTR [EBX] , AX ; Put its Low Order Word in IDT[0x10]
SHR EAX , 16 ; Get the High Order Word of the handler
MOV WORD PTR [EBX+06h] , AX ; Put it at the 4th WORD in IDT[0x10]
; --------------------------
LIDT [IDTR] ; Load the Interrupt Descriptor Table
;STI ; Enable Interrupts - BOOM !
INT 10h
I have commented the STI instruction but it still works. My question is: can we have a Trap and an Interrupt handler in the range 0x00 ... 0xFF? I mean how can we distinguish between them? Let's say I create the IDT to handle IRQs and other Harware Interrupts and now I want to create the IDT for software interrupts? What will happen? What should I do? Who am I? Who are you?
P.S: Thank you for your help.
Posted: Sat Feb 03, 2007 3:38 am
by SpooK
XCHG wrote:
I have commented the STI instruction but it still works. My question is: can we have a Trap and an Interrupt handler in the range 0x00 ... 0xFF? I mean how can we distinguish between them? Let's say I create the IDT to handle IRQs and other Harware Interrupts and now I want to create the IDT for software interrupts? What will happen? What should I do? Who am I? Who are you?
AFAIK, CLI/STI only applies to Interrupts (i.e. hardware generated interrupts). Software exceptions (or simply "Exceptions") will still be executed.
Also, if I am not mistaken, all Interrupts have Ring-0 privilege by design.
Trap gates are dependent on the TSS, which makes it more geared towards people who wish to utilize the Segmentation memory model (if you understand the depth/complexity of this design already).
You can simply make every IDT entry an "Interrupt Gate" and setup proper gate permissions (DPL). If you are using Ring-0 only, then you have very little you can do in protecting yourself against other Ring-0 code anyhow. If you are using the common Ring-0/Ring-3 segregation, then you are already set by the existence/use of the DPL. Just plug n' play
If you are trying to overload interrupts (make one interrupt do two things, depending on if it is hardware or software), then I have no advise for you as I haven't tried that... nor do I think it is a good idea.
HtH.
Posted: Sat Feb 03, 2007 8:30 am
by Otter
Yes, if you only want to call your itn 10h manually, sti is not necessary. But if you don't want to you should add "push ebx / pop ebx" to your handler ...
Posted: Sun Feb 04, 2007 2:22 am
by XCHG
Great! Thank you both for your help. Appreciations,
P.S: Spook? Good to see a familiar face in here!
Posted: Sun Feb 04, 2007 4:28 am
by SpooK
I thought something looked funny about this post... looks like I mixed up my technical jargon
Interrupts are hardware generated.
Exceptions are software generated.
I have modified the post to reflect the correct usage of such terms
Posted: Sun Feb 04, 2007 5:44 am
by Candy
SpooK wrote:I thought something looked funny about this post... looks like I mixed up my technical jargon
Interrupts are hardware generated.
Exceptions are software generated.
I have modified the post to reflect the correct usage of such terms
Physical interrupts (as in, IRQ, interrupt line etc) are hardware generated. Exceptions is your processor freaking out because you did something that you shouldn't have in your software. Software interrupts are people doing "INT 0x25".