I need an IDT tutorial... Or a fix?

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.
Warmaster199

I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

[attachment deleted by admin]
Tim

Re:I need an IDT tutorial... Or a fix?

Post by Tim »

I'd guess your GPF handler was doing something it shouldn't. Try putting in a CLI/HLT combination in front of the IRET, and moving it further and further forward until the system doesn't crash. Also, try to print the EIP of the invalid opcode; that will tell you whether your code is trying to branch to the wrong address.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

Warmaster199 wrote:
What I want from you people is a working IDT and IRQ/Exception handler system so I could see either what I did so horribly wrong, or use to replace my code all together. Or even give me a link to a tutorial? Everything works OK. Without any IRQs installed everything works... but as soon as I add an IRQ is totally mucks up... it's brutal... Can someone please help?
http://www.mega-tokyo.com/forum/index.p ... 21;start=0

I'm afraid we can't fix if we have no sources ;) however, there are plenty of possible reason for the exception to occur:
- you didn't remap the IRQ properly, but in that case you would get a bunch of EXC#08 (one per clock cycle). The Operating System Resources Center should have infos about how to fix this
- you didn't correctly set up your Interrupt Table Descriptor Register, but in that case, the IDT would hold garbage and reboots due to "triple fault"
- your IDT holds invalid offsets (but then where the hell does the exception messages come from ? VMware itself ??)

all these things can be tested by simply issuing an INT nn in your code rather than waiting an IRQ.

other options are
- there is a bug in your interrupt return that leads the code towards an invalid destination at IRQ return
- the same (similar) bug in your exception handler leads the code to an invalid (constant) opcode and thus the system enters a loop
Warmaster199

Re:I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

[attachment deleted by admin]
.bdjames

Re:I need an IDT tutorial... Or a fix?

Post by .bdjames »

void dead_isr()
{
__asm__("iret\n\t");
}

I would check and make sure this is:

dead_isr:
iret
ret

instead of:

dead_isr:
push ebp
mov ebp, esp
iret
pop ebp
ret

The makefiles do not work for me, I am just too lazy
Warmaster199

Re:I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

Sorry .bdjames... That didn't help. The stupid thing still messes up...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

1. i don't recommend to sti before calling the C code (in kernel/intr.s -- which looks familiar) also convert

Code: Select all

mov eax, _do_IRQ   ; we want the CALL to be EIP irrelevant
call eax      ; do IRQ
in

Code: Select all

call _do_IRQ
2. you seem to miss a out 20,20/ out a0,20 in the IRQ handler

3. your exception handler are written in C ? this means they will try to return with a simple RET while they should do an IRETD ... moreover, you completely ignore the fact that some exception (including #GPF) push an error code on the stack that must be popped by hand before the IRETD is issued ...

simple suggestion for debugging: when entering an exception handler (at the lowest possible level), increase nested_exception_counter and decrease it before leaving: this will prevent some exceptions loop and will help debugging. also try to stop the computer when a panic occur: don't just return on the error ;)

4. the "&" in &exception is useless: exception01 is the pointer to the function.
Warmaster199

Re:I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

I am sorry Pype... changing those things didn't really help anything... I deleted both the cli and sti and changed the call to what you said, but everything was the same... still dies. I had an outportb(0x20,0x20); as the last command in do_IRQ(int, regs);. It seems like it doesn't matter.

I don't think the IDT is bad because the exceptions run correctly(so it seems). What I don't get is why the GPF is issued right after my first sti(); in main();
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

Warmaster199 wrote: I don't think the IDT is bad because the exceptions run correctly(so it seems). What I don't get is why the GPF is issued right after my first sti(); in main();
It's likely you have a pending IRQ (man, your interrupts are disabled since you left realmode ! this now make ages for your CPU ;)

imho, what happens is that something gets wrong within your IRQ handler, which triggers a GPF exception, but your exception handlers techniques aren't working well (the code get executed, but isn't clean and returning from the handler raise another exception, etc :-@ )

now, having the EIP value of the exception could definitively help you (it should be located at [ebp+4], or [ebp+8] for exceptions that do have an error code like GPF, Task fault or stack fault ...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

and, btw,

Code: Select all

CTOS/Kernel> make
nasm -f aout -i../include/ -o start.o start.s
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include -c -o main.o main.c
In file included from main.c:2:
../include/asm/system.h:4: head.h: No such file or directory
In file included from main.c:3:
../include/vprintf.h:11: stdarg.h: No such file or directory
make: *** [main.o] Error 1
Warmaster199

Re:I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

[attachment deleted by admin]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

here's my low-level irq/exception handlers
http://cvs.sourceforge.net/cgi-bin/view ... ontrol.asm
http://cvs.sourceforge.net/cgi-bin/view ... terrpt.inc

you will probably need some files out of http://cvs.sourceforge.net/cgi-bin/view ... /head/asm/

to make it work :)

i think the problem is in your low-level stub handlers (the exception handlers simply can't work a.f.a.i.k. without a assembly stub)...
i'll try to disassemble your code to see what exactly happen when calling an interrupt and why it rises a GPF (this is the root of all evil)

If you wish to get more inspiration, you can give a look to src/kernel/interrpt.c which has a small function to dump the register contents in the case of an exception -- this could be handy to debug your OS, even on real hardware ;:)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

tried to compile under Linux -- but it seems that your OS is made under a DOS environment

Code: Select all

gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include -c -o main.o main.c
../include/vprintf.h:39: warning: `number' declared `static' but never defined
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include -c -o console.o console.c
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include -c -o vprintf.o vprintf.c
vprintf.c: In function `printk':
vprintf.c:21: warning: `buf' might be used uninitialized in this function
vprintf.c: In function `printf':
vprintf.c:195: warning: `buf' might be used uninitialized in this function
nasm -f aout -i../include/ -o register.o register.s
gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -I../include -c -o irq.o irq.c
irq.c:11: asm/errno.h: No such file or directory
In file included from irq.c:13:
../include/asm/irq.h:4: linkage.h: No such file or directory
../include/asm/irq.h:5: asm/segment.h: No such file or directory
irq.c:14: ptrace.h: No such file or directory
Warmaster199

Re:I need an IDT tutorial... Or a fix?

Post by Warmaster199 »

Yeah, I used to develop under Windows 98, Now I develop under Windows XP and I use VMWare to test (as you may know). So, for starters, I should try to work on my exception handlers (recoding them in assembler...). Since they are simple printk statements, I think that I should call printk within the ASM stublets... Correct me if I'm wrong, but I think it would be:

Code: Select all

EXTERN _printk

exp0 db "EXCEPTION 00: DIVIDE OR DIVISION OVERFLOW ERROR", 0

GLOBAL _exception00
_exception00:
    push exp0        ; I only know how to push normal vars, not pointers in asm...
    call _printk
    pop exp0
    iret
The thing I don't get is this: I don't know how I would pick up the error codes that are passed to them, would I pop them off the stack onto a temp variable? (I'm not good with assembler... I know how to do some of it.

I have to say Thanks Pype, for at least trying to fix my code, and for making me realize that my junk exceptions will never do...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:I need an IDT tutorial... Or a fix?

Post by Pype.Clicker »

Warmaster199 wrote:

Code: Select all

EXTERN _printk

exp0 db "EXCEPTION 00: DIVIDE OR DIVISION OVERFLOW ERROR", 0

GLOBAL _exception00
_exception00:
    push exp0        ; I only know how to push normal vars, not pointers in asm...
    call _printk
    pop exp0
    iret
this is a bit better, but not yet correct... because the exception handler can occur at any time (just as an interrupt), it must preserve the current CPU state.

Code: Select all

exc%1:
     pushad
 ;; handler code here
     popad
     iret
by the meantime, you cannot expect any segment register to be valid (except the stack segment) if your exception is processed with a trap-based mechanism (reminder: there is also a task-based exception handler in IA32 which can be handy in some pathological cases such as kernel stack overflow, etc.)
So it is wise to reset all the segment descriptors before doing anything else.

Code: Select all

%macro exception 2
%1:
   push dword %2
   jmp processException
%endmacro

%macro exception_nocode 2
%1:
   push dword 0
   push dword %2
   jmp processException
%endmacro
those macros will allow you to quickly define exceptions handlers that are all redirected to the same (shared) exception processing function.
The above code will guarantee you that, when processException is called, the stack frame is (top-down):
  • a identifier of the current exception (32-bits max). i suggest we store the exception number here, but virtually anything can be used :)
  • the error code, either pushed by the CPU or by the handler (in the latter case, it is defaulted to zero).
  • the CPU state that will be restored by an IRET command. note that its actual structure may change regarding to the faulty state (kernel, user or virtual mode)
you can create handlers with the following macro invocations:

Code: Select all

exception_nocode exc0,0      ; divide error
exception_nocode exc1,1      ; debug trap
exception_nocode exc2,2      ;  ??
exception_nocode exc3,3      ; breakpoint
exception_nocode exc4,4      ; overflow
exception_nocode exc5,5      ; bound
exception_nocode exc6,6      ; invalid opcode
exception_nocode exc7,7      ; no math

exception exc8,8      ; double fault
exception_nocode exc9,9      ; 80x87 overflow
exception exca,0x0a         ; invalid TSS
exception excb,0x0b         ; segment not present
exception excc,0x0c         ; stackfault
exception excd,0x0d         ; general protection
exception exce,0x0e         ; page fault
exception excf,0x0f         ; ??
Post Reply