Page 1 of 1

rmode switch fails in bochs

Posted: Sat Sep 13, 2008 6:43 pm
by neon
Hey everyone,

I have the following code. It is called from my 3rd stage protected mode bootloader program. It is supposed to switch into real mode and display a character (for a test) :

Code: Select all

bits 32
SystemReset:

	call	rmode_enable
	jmp	0:.reset16

bits 16
.reset16:

	mov ax, 0x0		; Reset segment registers to 0
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov	ss, ax
	mov sp, 0x9000
	lidt [idt_real]

	;; test--- print char using bios

	mov ah, 0xe
	mov al, '9',
	xor	bx, bx
	int 0x10

	cli
	hlt

idt_real:
	dw 0x3ff	; 256 entries, 4b each = 1K
	dd 0		; Real mode IVT at 0x0000
rmode_enable switches into real mode by simply clearing the pmode bit in cr0 and returns.

This routine works fine (displays the test characters and strings just fine) when running it from Virtual PC. However, I tested it on 2 versions of Bochs, both which fail.

Bochs 2.0.2 gets to the cli+hlt instructions with nothing at all displayed on screen;
Bochs 2.3.7 gives lot of 00010269272i[CPU0 ] LOCK prefix unallowed (op1=0xff, attr=0x0, mod=0xc0, nnn=7) warnings. When I shut it down it ends like this:

Code: Select all

00010269270i[CPU0 ]*snip* -- tons of the same lock prefix warning --
00010269271i[CPU0 ] LOCK prefix unallowed (op1=0xff, attr=0x0, mod=0xc0, nnn=7)
00010269272i[CPU0 ] LOCK prefix unallowed (op1=0xff, attr=0x0, mod=0xc0, nnn=7)
00013600000p[WGUI ] >>PANIC<< POWER button turned off.
00013600000i[CPU0 ] CPU is in real mode (active)
00013600000i[CPU0 ] CS.d_b = 32 bit
00013600000i[CPU0 ] SS.d_b = 32 bit
00013600000i[CPU0 ] EFER   = 0x00000000
00013600000i[CPU0 ] | RAX=00000000000007e4  RBX=00000000001fa000
00013600000i[CPU0 ] | RCX=0000000000000206  RDX=0000000000000007
00013600000i[CPU0 ] | RSP=00000000010f5b1c  RBP=00000000010f9078
00013600000i[CPU0 ] | RSI=00000000001000cd  RDI=0000000000000852
00013600000i[CPU0 ] |  R8=0000000000000000   R9=0000000000000000
00013600000i[CPU0 ] | R10=0000000000000000  R11=0000000000000000
00013600000i[CPU0 ] | R12=0000000000000000  R13=0000000000000000
00013600000i[CPU0 ] | R14=0000000000000000  R15=0000000000000000
00013600000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt OF df if tf sf zf af pf CF
00013600000i[CPU0 ] | SEG selector     base    limit G D
00013600000i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00013600000i[CPU0 ] |  CS:0000( 0001| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  DS:0000( 0002| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  SS:0000( 0002| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  ES:0000( 0002| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  FS:0000( 0002| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  GS:0000( 0002| 0|  0) 00000000 000fffff 1 1
00013600000i[CPU0 ] |  MSR_FS_BASE:0000000000000000
00013600000i[CPU0 ] |  MSR_GS_BASE:0000000000000000
00013600000i[CPU0 ] | RIP=00000000000076ce (00000000000076ce)
00013600000i[CPU0 ] | CR0=0x60000010 CR1=0x0 CR2=0x0000000000000000
00013600000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00013600000i[CPU0 ] >> add byte ptr ds:[eax], al : 0000
What can cause this to work in VirtualPC but not bochs? Usually it is the other way around :p

In the above, RIP contains an odd value however it makes no sense as they both fail at the bios INT 0x10 call :/ ie, they both work fine until we get further into the int 0x10 call when running it from the debugger...it never returns from the int 0x10 before crashing.

Does anyone have any suggestions that may help? If there is additional information you need, please let me know and I would be glad to share it.

Thanks for any suggestions of any kind :D

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 7:49 pm
by neon
Little update...

According to the debugger, Bochs starts dying early in the int call (Here I am single stepping at the int 0x10 call) :

Code: Select all

<0> [0x00000788] 0000:0788 <unk. ctxt>: int 0x10
<0> [0x000c012c] c000:012c <unk. ctxt>: pushfd
<0> [0x000c012d] c000:012d <unk. ctxt>: cmp ah, 0x0f
<0> [0x000c0130] c000:0130 <unk. ctxt>: jnz .+0x00000006 <0x000c0138>
<0> [0x000c0138] c000:0138 <unk. ctxt>: cmp ah, 0x1a
<0> [0x000c013b] c000:013b <unk. ctxt>: jnz .+0x00000006 <0x000c0143>
<0> [0x000c0143] c000:0143 <unk. ctxt>: cmp ah, 0x0b
<0> [0x000c0146] c000:0146 <unk. ctxt>: jnz .+0x00000006 <0x000c014e>
<0> [0x000c014e] c000:014e <unk. ctxt>: cmp eax, 0x06751103
<0> [0x000c0153] c000:0153 <unk. ctxt>: call .+0x9be96793 <0x9bf568eb>
bx_dbg_read_linear: physical_memory_read_error <phys=0x9bf56eb, lin=0x000000009bf568eb>
<0> [0x0000fff53] f000:ff53 <unk. ctxt>: iretd
bx_dbg_read_linear: physical_memory_read_error <phys=0xc000714b, lin=0x000000c000714b>
<0> [0x0000fff53] f000:ff53 <unk. ctxt>: iretd
<0> [0x0086690b] 0002:8668eb <unk. ctxt>: add byte ptr ds:[eax], al
<0> [0x0086690d] 0002:8668ed <unk. ctxt>: add byte ptr ds:[eax], al
*snip*...continues like this... cs:eip look completely wrong
Not sure why we are getting physical memory read errors though... :/ Does anyone have any ideas?

Ill update if I find more information that may help (or find a solution :) )

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 9:16 pm
by cr2
Where have you loaded your stage 3 bootloader to?

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 9:32 pm
by neon
At the moment its at 1mb. (Yes I got to change that.)

Nonetheless it is a separate program. The 2nd stage bootloader currently passes the address of SystemReset() so that we can call it from the program. SystemReset() is located around address 0x700 within the 2nd stage bootloader (loaded at 0x500). I dont think it matters though as we switch to rmode and do all rmode functionality below 1MB.

The errors seem somewhat random--I can get it to not crash but it still fails to display anything only in Bochs :/

Thanks for any help :)

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 9:36 pm
by cr2
neon wrote:I can get it to not crash but it still fails to display anything only in Bochs
Are you saying that you can get it to work outside of bochs?

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 9:40 pm
by neon
Are you saying that you can get it to work outside of bochs?
It always works perfectly fine with VirtualPC...It only seems to happen in Bochs. I tried two versions of Bochs so far and it fails on both of them. (I can always get an older version just in case its a bug...)

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 9:43 pm
by cr2
It might just be a result of a bug in bochs...

bochs bug reports

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:13 pm
by neon
I found a way to make it work with both VirtualPC and Bochs :D

I just created two new 16bit segments in the protected mode gdt and used it like so:

Code: Select all

bits 32
SystemReset:

	cli
	jmp CODE_SEL_16BIT:.reset16

bits 16

.reset16:

	cli
    mov eax, cr0
    and al, 0FEh
    mov cr0, eax

	xor	eax, eax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ds, ax
	mov	ss, ax
	mov esp, 0x5000

	;; test--- print char using bios

	mov ah, 0xe
	mov al, '9'
	xor	ebx, ebx

	int 0x10

	cli
	hlt
*ugh* all that trouble finding a bug and the solution is so simple :p *sigh*

Thanks for your suggestions though :D

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:17 pm
by cr2
I'm glad it worked. :D :wink: :) :twisted: =D> \:D/ :lol:

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:23 pm
by neon
I actually spoke to soon. Its displaying the character now but the INT call doesn't seem to ever return :/

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:31 pm
by cr2
Can we see what is being executed(using the bochs debugger)?

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:38 pm
by neon
According to the debugger its IRET instruction is returning to invalid code right now (I am getting LOCK prefix unallowed errors in the log). Ill post more info if I find any.

Re: rmode switch fails in bochs

Posted: Sat Sep 13, 2008 10:49 pm
by neon
*ugh*. I got problem #2 fixed. It now properly displays (and returns) from the INT call on both Bochs and VirtualPC. I was improperly setting cs.

I just hope a problem #3 does not arise... :)

*edit: Nah, Everything is working fine now. Its switching to rmode and calling the bios fine and switching back to pmode and properly returning back to stage 3.

I think I can conclude that this problem is solved :)