Page 2 of 2

Posted: Mon Apr 21, 2008 1:31 am
by White-spirit
My bootloader ( and also the kernel loader for GRUB ) already calls FINIT :/
I'ill try to remove them to see what happens ...

Thanks .

Posted: Mon Apr 21, 2008 5:15 am
by White-spirit
I've removed the floating-point instructions and the printf calls ( stdargs.h ), but it's still the same...

If I remove the IDT initialisation and test a division by zero, I get an int 13 on the bochs console instead of 0 ...

I'm still confused, I've tried all possible solutions so I think I give up :oops:

At least, here's the error message :

Code: Select all

(0).[28907212] [0x00100be1] 0008:00100be1 (unk. ctxt): idiv eax, dword ptr ss:[ebp+0xffffffd4] ; f77dd4
00028907212e[CPU  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting

Posted: Mon Apr 21, 2008 5:40 am
by zaleschiemilgabriel
Have you also removed the line where it tries to divide 5 / 0 ?

Posted: Mon Apr 21, 2008 5:52 am
by Combuster
White-spirit wrote:If I remove the IDT initialisation and test a division by zero, I get an int 13 on the bochs console instead of 0 ...
Obviously, without an IDT any interrupt will crash. Try causing a divison by zero after creating the IDT and see which handler gets called then

And still, I get the idea you haven't done the singlestepping with bochs' debugger to see what is actually going on.

Posted: Mon Apr 21, 2008 5:59 am
by White-spirit
If I remove the div by zero line, it works fine because there's no interrupts happening, but if I try int $0x4 or 5/0, I get the GPF's :s .

I've changed the idt.s code, so here's the new code :

Code: Select all

format elf

public idt_flush

extrn isr_handler



idt_flush:

push ebp

mov ebp, esp

mov ebx, [esp+8]

lidt [ebx]

leave

ret



public isr0

isr0:

cli

push 0

push 0

jmp isr_common_stub



rept 31 id

{

public isr#id

isr#id:

cli

if id = 8 | ( id > 9 & id < 15 )

push 0

end if

push id

jmp isr_common_stub

}



isr_common_stub:

pusha

mov ax,ds

push eax

mov ax,0x10				; ax <== 10h

mov ds,ax				; ds <== 10h

mov es,ax				; es <== 10h

mov fs,ax				; fs <== 10h

mov gs,ax				; eg <== 10h

call isr_handler

pop ebx					; restores the old values

mov ds,bx

mov es,bx

mov fs,bx

mov gs,bx

popa

add esp, 16

sti

leave

iret

I've changed "add esp, 8" to "add esp, 16" because pusha pushes eight 16 bits registers, and for each register, ESP must be incremented by 2, so it's 16 .

The result has changed, I see yet only few lines like theses :

Code: Select all

Interruption 4 , error code : 0x100be3 ( 1051619 ) // caused by int $0x4 I guess
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
Interruption 8 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
I think i've solved a little part from the problem, so I think I will not give up :D

Thanks .

Posted: Mon Apr 21, 2008 6:21 am
by Combuster
Now i'm sure you have never touched the debugger as it would be absolutely obvious what goes wrong there - your stack is bogus. You just changed the behaviour of your bug
I've changed "add esp, 8" to "add esp, 16" because pusha pushes eight 16 bits registers, and for each register, ESP must be incremented by 2, so it's 16.
. you have 8 dwords = 8 * 4 = 32 bytes. The adjustment of ESP is for something different.
if id = 8 | ( id > 9 & id < 15 )
if you are checking for interrupts with an error code, you inverted the check, and the condition is incorrect. (wrt #PF and #AC)
Interruption 8 , error code : 0x0 ( 0 )
Interruption 13 , error code : 0x0 ( 0 )
You can NOT continue after a double-fault.
sti
leave
iret
You're absolutely clueless about what this does, no? Do look it up in the manuals and I hope you will understand why this is absolutely pointless.

Posted: Mon Apr 21, 2008 6:51 am
by White-spirit
Combuster wrote:
White-spirit wrote:If I remove the IDT initialisation and test a division by zero, I get an int 13 on the bochs console instead of 0 ...
Obviously, without an IDT any interrupt will crash. Try causing a divison by zero after creating the IDT and see which handler gets called then

And still, I get the idea you haven't done the singlestepping with bochs' debugger to see what is actually going on.
Here are the informations i got from the debugger :

The GDT :

Code: Select all

Global Descriptor Table (base=0x00108000, limit=39):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, linearaddr=00000000, limit=fffff * 4Kbytes, Execute/Read, 32-bit
GDT[0x02]=Data segment, linearaddr=00000000, limit=fffff * 4Kbytes, Read/Write, Accessed
GDT[0x03]=Code segment, linearaddr=00000000, limit=fffff * 4Kbytes, Execute/Read, 32-bit
GDT[0x04]=Data segment, linearaddr=00000000, limit=fffff * 4Kbytes, Read/Write
The IDT :

Code: Select all

Interrupt Descriptor Table (base=0x00108060, limit=2047):
IDT[0x00]=32-Bit Interrupt Gate target=0x0008:0x00103134, DPL=0
IDT[0x01]=32-Bit Interrupt Gate target=0x0008:0x0010313e, DPL=0
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0x00103146, DPL=0
IDT[0x03]=32-Bit Interrupt Gate target=0x0008:0x0010314e, DPL=0
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x00103156, DPL=0
IDT[0x05]=32-Bit Interrupt Gate target=0x0008:0x0010315e, DPL=0
IDT[0x06]=32-Bit Interrupt Gate target=0x0008:0x00103166, DPL=0
IDT[0x07]=32-Bit Interrupt Gate target=0x0008:0x0010316e, DPL=0
IDT[0x08]=32-Bit Interrupt Gate target=0x0008:0x00103176, DPL=0
IDT[0x09]=32-Bit Interrupt Gate target=0x0008:0x0010317d, DPL=0
IDT[0x0a]=32-Bit Interrupt Gate target=0x0008:0x00103182, DPL=0
IDT[0x0b]=32-Bit Interrupt Gate target=0x0008:0x00103189, DPL=0
IDT[0x0c]=32-Bit Interrupt Gate target=0x0008:0x00103190, DPL=0
IDT[0x0d]=32-Bit Interrupt Gate target=0x0008:0x00103197, DPL=0
IDT[0x0e]=32-Bit Interrupt Gate target=0x0008:0x0010319e, DPL=0
IDT[0x0f]=32-Bit Interrupt Gate target=0x0008:0x001031a5, DPL=0
IDT[0x10]=32-Bit Interrupt Gate target=0x0008:0x001031aa, DPL=0
IDT[0x11]=32-Bit Interrupt Gate target=0x0008:0x001031af, DPL=0
IDT[0x12]=32-Bit Interrupt Gate target=0x0008:0x001031b4, DPL=0
IDT[0x13]=32-Bit Interrupt Gate target=0x0008:0x001031b9, DPL=0
IDT[0x14]=32-Bit Interrupt Gate target=0x0008:0x001031be, DPL=0
IDT[0x15]=32-Bit Interrupt Gate target=0x0008:0x001031c3, DPL=0
IDT[0x16]=32-Bit Interrupt Gate target=0x0008:0x001031c8, DPL=0
IDT[0x17]=32-Bit Interrupt Gate target=0x0008:0x001031cd, DPL=0
IDT[0x18]=32-Bit Interrupt Gate target=0x0008:0x001031d2, DPL=0
IDT[0x19]=32-Bit Interrupt Gate target=0x0008:0x001031d7, DPL=0
IDT[0x1a]=32-Bit Interrupt Gate target=0x0008:0x001031dc, DPL=0
IDT[0x1b]=32-Bit Interrupt Gate target=0x0008:0x001031e1, DPL=0
IDT[0x1c]=32-Bit Interrupt Gate target=0x0008:0x001031e6, DPL=0
IDT[0x1d]=32-Bit Interrupt Gate target=0x0008:0x001031eb, DPL=0
IDT[0x1e]=32-Bit Interrupt Gate target=0x0008:0x001031f0, DPL=0
IDT[0x1f]=32-Bit Interrupt Gate target=0x0008:0x001031f5, DPL=0
IDT[0x20]=32-Bit Interrupt Gate target=0x0008:0x00103234, DPL=0
IDT[0x21]=32-Bit Interrupt Gate target=0x0008:0x0010323b, DPL=0
IDT[0x22]=32-Bit Interrupt Gate target=0x0008:0x00103242, DPL=0
IDT[0x23]=32-Bit Interrupt Gate target=0x0008:0x00103249, DPL=0
IDT[0x24]=32-Bit Interrupt Gate target=0x0008:0x00103250, DPL=0
IDT[0x25]=32-Bit Interrupt Gate target=0x0008:0x00103257, DPL=0
IDT[0x26]=32-Bit Interrupt Gate target=0x0008:0x0010325e, DPL=0
IDT[0x27]=32-Bit Interrupt Gate target=0x0008:0x00103265, DPL=0
IDT[0x28]=32-Bit Interrupt Gate target=0x0008:0x0010326c, DPL=0
IDT[0x29]=32-Bit Interrupt Gate target=0x0008:0x00103273, DPL=0
IDT[0x2a]=32-Bit Interrupt Gate target=0x0008:0x0010327a, DPL=0
IDT[0x2b]=32-Bit Interrupt Gate target=0x0008:0x00103281, DPL=0
IDT[0x2c]=32-Bit Interrupt Gate target=0x0008:0x00103288, DPL=0
IDT[0x2d]=32-Bit Interrupt Gate target=0x0008:0x0010328f, DPL=0
IDT[0x2e]=32-Bit Interrupt Gate target=0x0008:0x00103296, DPL=0
IDT[0x2f]=32-Bit Interrupt Gate target=0x0008:0x0010329d, DPL=0
And by debugging step by step ( the virtual breakpoint address is : 0x0008:0x00103156 ), I get this :

Code: Select all

(0) [0x0010321d] 0008:0010321d (unk. ctxt): sti                       ; fb
<bochs:66>
Next at t=28104634
(0) [0x0010321e] 0008:0010321e (unk. ctxt): leave                     ; c9
<bochs:67>
Next at t=28104635
(0) [0x0010321f] 0008:0010321f (unk. ctxt): iretd                     ; cf
<bochs:68>
00028104635e[CPU  ] fetch_raw_descriptor: GDT: index (d007)1a00 > limit (27)
Next at t=28104635
(0) [0x00103197] 0008:00103197 (unk. ctxt): cli                       ; fa
<bochs:69>
Next at t=28104636
(0) [0x00103198] 0008:00103198 (unk. ctxt): push 0x00000000           ; 6a00
<bochs:70>
Next at t=28104637
(0) [0x0010319a] 0008:0010319a (unk. ctxt): push 0x0000000d           ; 6a0d
<bochs:71>
Next at t=28104638
(0) [0x0010319c] 0008:0010319c (unk. ctxt): jmp .+0x0000005c (0x001031fa) ; eb5c<bochs:72>
Next at t=28104639
(0) [0x001031fa] 0008:001031fa (unk. ctxt): pushad                    ; 60
...
So it's something with iret ...

Posted: Mon Apr 21, 2008 7:06 am
by White-spirit
Thanks, you're right Combuster, I use "if ~ ( id = 8 | ( id > 9 & id < 15 ) )" yet .

But it's still the same :/

Posted: Mon Apr 21, 2008 7:28 am
by White-spirit
Int $0x4 works fine yet after correcting the fasm condition .
But the division by zero doesn't, of course, it doesn't stop the division ...
So I'ill ignore that because it's normal, and proceed to the multi-tasking on my OS ( then I can kill processes who GPF's ) .

And I understand now why there are GPF's, it's because with the false fasm condition the interrupts with error codes are doing 3 pushes .

Thanks Combuster :)