Mysterious Error[solved]

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.
Post Reply
thisisausername
Posts: 2
Joined: Fri Mar 25, 2016 5:56 am

Mysterious Error[solved]

Post by thisisausername »

Hello everyone. I encounter a wired bug recently in my own OS:
A cpu error interrupt 0x00(Divsion by zero) occurs always at a specific point.

After enabling A20, protected mode and setting up gdt, main() was loaded immediately.
Here is my main() in main.c:

Code: Select all

void Main(void)
{	
	initPIC();
	initVga();
	vgaClearScreen(0x60);
	drawBox(320,20,0,0,0x60);//temporaly desktop bg
	drawMouse((video_mode_info->width-16)/2, (video_mode_info->height-16)/2, 11, 16, 0x2e);
	char s[60];
	sprintf(s,"screen x: %d screen y: %d",video_mode_info->width,video_mode_info->height);
	putstr(4,20,0xff,s);
	while(1)
	{
		ioHLT();
	}
}
in main() i initialized firstly PIC and disabled all IRQ-interrupt at the same time. And then i initialized VGA by setting up palette and enabled interrupt flag with "sti" also. while "vgaClearScreen(0x60)" the bug appeared. Because I haven't set IDT yet so interrupt 0x00 poped up and also triple fault making my screen look like this:
http://imgur.com/2NIK6hA

in bochs' debug mode this bug will appear in a little different place and making my screen look like this:

http://imgur.com/h8Z4DXa

and here is the code of vgaClearScreen():

Code: Select all

void vgaClearScreen(char color_code)
{
	unsigned short i;
	for(i=0;i<=0xf9ff;i++)
	{
		video_mode_info->vram[i]=color_code;
	}
	
	return;
}
At first i thought i might make some mistake in vgaClearScreen(), but after i dissembling it, it confused me even more. Here are dissembled codes:

Code: Select all

;0x000107c4:

mov eax, dword ptr ds:0x00012808 ; a108280100
; ds:0x00012808->;struct contains infomation about vram, height, width...etc. (=0x00010130)

mov edx, dword ptr ds:[eax+16] ; 8b5010
;edx =vram: 0x000a0000

movzx eax, word ptr ss:[ebp-2]
; ss:[ebp-2]-> unsigned short i

add edx, eax
; 0x000a0000+i

movzx eax, byte ptr ss:[ebp-20] ; 0fb645ec

mov byte ptr ds:[edx], al ; 8802
; al=char color_code

movzx eax, word ptr ss:[ebp-2] ; 0fb745fe

add eax, 0x00000001 ; 83c001
; i++

mov word ptr ss:[ebp-2], ax ; 668945fe

cmp word ptr ss:[ebp-2], 0xf9ff ; 66817dfefff9
jbe .-39 (0x000107c4) ; 76d9
; if(i<=0xf9ff) {goto 0x000107c4;}
And it's obviously, it contains even no a division instructors, and that is the point that confused me.

However i have tried some ways to try to solve this problem. Like setting up idt and hook interrupt 0x00 on a handler, in which contain only somting like "ret" and "iretd". Tring to ignore the problem only. It worked. But the problem is still there. Please help me solving with it. Thank you.

Btw, i tried also not to "sti" in the end of the function "initVga()", but right in front of while(1){ioHLT();}. The same "Divsion by zero" error will still pop up but this time stop at the instructor "ret" from ioHLT().

Following are log from bochs:
00014918926i[BIOS ] Booting from 0000:7c00
00051195609e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x00)
00051195609e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00051195609e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00051195609i[CPU0 ] CPU is in protected mode (active)
00051195609i[CPU0 ] CS.mode = 32 bit
00051195609i[CPU0 ] SS.mode = 32 bit
00051195609i[CPU0 ] EFER = 0x00000000
00051195609i[CPU0 ] | EAX=00000060 EBX=00000002 ECX=00000021 EDX=000a1994
00051195609i[CPU0 ] | ESP=00016774 EBP=00016788 ESI=000e0000 EDI=0000ffac
00051195609i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf AF PF CF
00051195609i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00051195609i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00051195609i[CPU0 ] | EIP=0001082d (0001082d)
00051195609i[CPU0 ] | CR0=0x60000011 CR2=0x00000000
00051195609i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00051195609i[CPU0 ] 0x000000000001082d>> mov eax, dword ptr ds:0x00012810 : A110280100
00051195609p[CPU0 ] >>PANIC<< exception(): 3rd (13) exception with no resolution
00051195609i[WINGUI] dimension update x=640 y=400 fontheight=0 fontwidth=0 bpp=8

Thank you for your patient.
Last edited by thisisausername on Fri Mar 25, 2016 9:42 am, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Mysterious Error

Post by Octocontrabass »

You've programmed the PIC to send IRQ 0 to interrupt 0.
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Mysterious Error

Post by BrightLight »

Try to modify your temporary divide by zero handler to do something like this:

Code: Select all

pusha
mov rdi, 0xB8000
mov byte[rdi], 'x'
not byte[rdi+1]
mov al, 0x20
out 0x20, al
popa
iret
If it gets called repeatedly, then you've mapped PIC IRQ 0 to INT 0x00.
Anyway, it's quite odd that you've set up the PIC before even the IDT.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
thisisausername
Posts: 2
Joined: Fri Mar 25, 2016 5:56 am

Re: Mysterious Error[solved]

Post by thisisausername »

Thanks for Octocontrabass and omarrx024's reply.
I looked into initPIC() and found that I sent icw2's data in wrong port.
Now everything work perfectly!!!

Thank you!
Post Reply