Page 1 of 2

Ok, what's wrong?

Posted: Sun May 20, 2012 2:01 pm
by Mikemk
This is the code to enter pmode:

Code: Select all

org 0x7c00
...
bits 32
contA:
	cli
	lgdt [endGDT] ; I have tried this here and after "mov cr0, eax"
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	xor eax, eax ; I have tried with and without these four lines.
	xor ebx, ebx
	xor edx, edx
	xor ecx, ecx
	jmp 0x8:pmode ; I have used memory dumps, log files, hlt instructions, etc. and determined that this line throws an error.
...
pmode:
	hlt
the relevant parts of bochs' log:

Code: Select all

00017825015i[BIOS ] Booting from 0000:7c00
00018000000i[WGUI ] dimension update x=640 y=400 fontheight=0 fontwidth=0 bpp=8
00045097126e[CPU0 ] jump_protected: gate type 0 unsupported
00045097126e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00045097126e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00045097126i[CPU0 ] CPU is in protected mode (active)
00045097126i[CPU0 ] CS.d_b = 16 bit
00045097126i[CPU0 ] SS.d_b = 16 bit
00045097126i[CPU0 ] EFER   = 0x00000000
00045097126i[CPU0 ] | RAX=0000000060000000  RBX=0000000000000000
00045097126i[CPU0 ] | RCX=0000000000000000  RDX=0000000000000000
00045097126i[CPU0 ] | RSP=000000000000ffff  RBP=000000000000ffff
00045097126i[CPU0 ] | RSI=00000000000e0000  RDI=000000000000ffac
00045097126i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00045097126i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00045097126i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00045097126i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00045097126i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df if tf sf ZF af PF cf
00045097126i[CPU0 ] | SEG selector     base    limit G D
00045097126i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00045097126i[CPU0 ] |  CS:0000( 0004| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  DS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  SS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  ES:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  FS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  GS:0000( 0005| 0|  0) 00000000 0000ffff 0 0
00045097126i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00045097126i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00045097126i[CPU0 ] | RIP=0000000000007cf3 (0000000000007cf3)
00045097126i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00045097126i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00045097126i[CPU0 ] 0x0000000000007cf3>> jmp far 0008:7d53 : EA537D0800
the list file:

Code: Select all

     1                                  org 0x7c00
...
   111                                  bits 32
   112                                  contA:
   113 000000D8 FA                      	cli
   114 000000D9 0F0115[A8020000]        	lgdt [endGDT]
   115 000000E0 0F20C0                  	mov eax, cr0
   116 000000E3 0D01000000              	or eax, 1
   117 000000E8 0F22C0                  	mov cr0, eax
   118 000000EB 31C0                    	xor eax, eax
   119 000000ED 31DB                    	xor ebx, ebx
   120 000000EF 31D2                    	xor edx, edx
   121 000000F1 31C9                    	xor ecx, ecx
   122 000000F3 EA537D00000800          	jmp 0x8:pmode
...
   162                                  pmode:
   163 00000153 F4                      	hlt
I am following these instructions. Why is it triple faulting?

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 2:06 pm
by Nessphoro
Is "endGDT" referring to the end of the GDT structure?

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 2:10 pm
by Mikemk
Sorry, I meant to post that:

Code: Select all

GDT:
align 8
	dd 0
	dd 0 
 
	dw 0FFFFh
	dw 0
	db 0
	db 10011010b
	db 11001111b
;	db 01011001b
;	db 11110011b
	db 0 	
	
	dw 0FFFFh
	dw 0
	db 0
	db 10010010b
	db 11001111b
	db 0

endGDT:
	dw endGDT - GDT - 1 	; limit (Size of GDT)
	dd GDT

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 2:40 pm
by iansjack
"00045097126e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00045097126e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)"

That's what's wrong. Single step through your code in a debugger and check the values of those selectors.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 2:44 pm
by DavidCooper
Shouldn't the bits 32 directive come after you've jumped into protected mode? It's generating extra 00 00 bytes which are being run as add instructions, adding whatever is in al to whatever memory location is being pointed at by ax.

[Edit: correction - that's actually what a pair of zero bytes would do in 32-bit mode, but as it's in real mode it'll add whatever's in al to whatever memory location is pointed at by bx+si.]
114 000000D9 0F0115[A8020000] lgdt [endGDT]
...
116 000000E3 0D01000000 or eax, 1
By the way, you forgot to mention spelling after grammar in your sig.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 3:10 pm
by Combuster
Please learn how to program. You're still using a crowbar to break out random bits from somewhere and then dump them together in random order.
xor eax, eax
xor ebx, ebx
xor edx, edx
xor ecx, ecx
Is useless
bits 32
is at the wrong place.

And since you didn't post all the code, I'm going to assume all the previous errors apply as well.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 6:47 pm
by Mikemk
I put the bits 32 directive right after enabling the A20 address line. As I understand it, [seemingly] random things can occur if I try to run 16 bit code after enabling a20?

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 6:50 pm
by bluemoon
debug is not guesswork. show your reason for suspect such issue.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 7:04 pm
by Mikemk
Because it happened... and if I put a hlt instruction right before the jump, it gives the message "The CPU has been disabled by the guest operating system." Debuggers say the problem is the GDT

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 8:01 pm
by neon
Are you really sure that you want to enter protected mode in a vbr given the limitations? In any case, as mentioned ealier, use bits 32 after having already performed the mode switch. The message that you received when using HLT is completely fine and does not indicate an error.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 8:17 pm
by bluemoon
m12 wrote:I put the bits 32 directive right after enabling the A20 address line. As I understand it, [seemingly] random things can occur if I try to run 16 bit code after enabling a20?
There is no problem running 16 bit code after enable A20. In your case the CPU stay on 16 bit mode before and after enable A20, the problem is you cannot run 32bit code(since the bits 32) in 16 bit environment.

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 11:03 pm
by LindusSystem
One thing:
Sometimes I used to get the same error "interrupt(): gate descriptor is not valid sys seg" and GPF

It got fixed in my kernel after I did
mov ax,0x08
mov cs,ax
mov ax,0x10
mov ds ,ax
mov es,ax
mov gs,ax
mov fs,ax
The same way have you initialized the segments before using other bootloader stuff.
For example: mov ax, 0x7C00 ;Depends where you want it to be
mov ,etc,etc

Re: Ok, what's wrong?

Posted: Sun May 20, 2012 11:17 pm
by Combuster
LindusSystem wrote:It got fixed in my kernel after I did
mov cs,ax
Your kernel is obviously never getting executed... :roll:

If you want a crash, use that.

Re: Ok, what's wrong?

Posted: Mon May 21, 2012 12:41 am
by bluemoon
LindusSystem wrote: It got fixed in my kernel after I did
mov ax,0x08
mov cs,ax
I recommend you to switch to other sane assembler now.

Re: Ok, what's wrong?

Posted: Mon May 21, 2012 6:44 am
by Mikemk
thank you, everyone, I got it working with

Code: Select all

	mov ax,0x10
	mov ds ,ax
	mov es,ax
	mov gs,ax
	mov fs,ax
	jmp 0x8:pmode