I need an IDT tutorial... Or a fix?
Re:I need an IDT tutorial... Or a fix?
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.
- Pype.Clicker
- 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?
http://www.mega-tokyo.com/forum/index.p ... 21;start=0Warmaster199 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?
I'm afraid we can't fix if we have no sources

- 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
Re:I need an IDT tutorial... Or a fix?
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
{
__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
Re:I need an IDT tutorial... Or a fix?
Sorry .bdjames... That didn't help. The stupid thing still messes up...
- Pype.Clicker
- 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?
1. i don't recommend to sti before calling the C code (in kernel/intr.s -- which looks familiar) also convert
in
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.
Code: Select all
mov eax, _do_IRQ ; we want the CALL to be EIP irrelevant
call eax ; do IRQ
Code: Select all
call _do_IRQ
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.
Re:I need an IDT tutorial... Or a fix?
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();
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();
- Pype.Clicker
- 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?
It's likely you have a pending IRQ (man, your interrupts are disabled since you left realmode ! this now make ages for your CPUWarmaster199 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();

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 ...
- Pype.Clicker
- 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?
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
- Pype.Clicker
- 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?
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 ;:)
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 ;:)
- Pype.Clicker
- 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?
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
Re:I need an IDT tutorial... Or a fix?
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:
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...
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
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...
- Pype.Clicker
- 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?
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.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
Code: Select all
exc%1:
pushad
;; handler code here
popad
iret
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
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)
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 ; ??