Page 1 of 1

32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 8:07 am
by TryHarder
Hey everybody,
I have a working OS that was developed for x86 and runs on 'qemu'. Now, I want to make a x86_64 version, which will run in long mode.
My first step was to run current working OS on 86_64 qemu arch. Intel and AMD manuals claims that every x86_64 architecture is fully compatible with code that was written for x86 machines. So, as far as I understand it, my OS should run on 'qemu-system-x86_64' without any additional hacks (or even recompilation). So the first question is: am I right about that?
Next, I'm getting fatal error (additional info available, if necessary) that caused by qemu segmentation mechanism. Who is guilty, me or qemu-system-x86_64 (recall that in 'qemu' it works fine)?
Thanks for help.

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 8:25 am
by Chandra
TryHarder wrote:So, as far as I understand it, my OS should run on 'qemu-system-x86_64' without any additional hacks (or even recompilation). So the first question is: am I right about that?
Right. Mine works fine.
TryHarder wrote:Next, I'm getting fatal error (additional info available, if necessary) that caused by qemu segmentation mechanism. Who is guilty, me or qemu-system-x86_64 (recall that in 'qemu' it works fine)?
Your code.

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 8:50 am
by Love4Boobies
TryHarder wrote:Intel and AMD manuals claims that every x86_64 architecture is fully compatible with code that was written for x86 machines. So, as far as I understand it, my OS should run on 'qemu-system-x86_64' without any additional hacks (or even recompilation). So the first question is: am I right about that?
Looks like you answered yourself. Also, don't you also use an x86-64 CPU? Have you never noticed that you can install a legacy 32-bit OS on it without taking any special steps? Can't you do the math?
Next, I'm getting fatal error (additional info available, if necessary) that caused by qemu segmentation mechanism. Who is guilty, me or qemu-system-x86_64 (recall that in 'qemu' it works fine)?
As in a segmentation fault (which is not a QEMU mechanism)? If that's the case, it's not your fault. Which host OS are you using?

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 8:57 am
by xenos
Could you provide some more information about the QEMU crash?

I use both 32 and 64 bit versions of QEMU for testing my OS kernel (which targets both x86 and x86_64 architectures). If I run the 32 bit version of my kernel on qemu-system-x86_64, it works absolutely fine (except for giving me a warning that I'm running a 32 bit kernel on a 64 bit capable CPU ;)).

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 9:10 am
by TryHarder
The error is:
qemu: fatal: Trying to execute code outside RAM or ROM at 0x000000010010002e


Intro: kernel loaded into 0x100000 physical address, just after low MB.
But the entry point is 0xF0100000, we want the kernel at the top of virtual address space.
So 0xF0100000 -> 0x100000 mapping is done with segments (paging is off yet).
KERNBASE = 0xF0000000

Code: Select all

	
#define	RELOC(x) ((x) - KERNBASE)

.set CODE_SEL,0x8		# index of code seg within mygdt
.set DATA_SEL,0x10		# index of data seg within mygdt

        # Establish our own GDT in place of the boot loader's temporary GDT.
	lgdt	RELOC(mygdtdesc)		# load descriptor table

	[b]At this point we have protected mode with no paging.[/b]
	movl	$DATA_SEL, %eax			# Data segment selector
	movw	%ax,%ds				# -> DS: Data Segment
	movw	%ax,%es				# -> ES: Extra Segment
	movw	%ax,%ss				# -> SS: Stack Segment
	ljmp	$CODE_SEL,$relocated		# reload CS by jumping (fail here)
relocated: (logical = 0xF010.....)
        ....
.data
mygdt:
	SEG_NULL				# null seg
	SEG(STA_X|STA_R, -KERNBASE, 0xffffffff)	# code seg
	SEG(STA_W, -KERNBASE, 0xffffffff)	# data seg
mygdtdesc:
	.word	0x17			# sizeof(mygdt) - 1
	.long	RELOC(mygdt)		# address mygdt

As you may see, segment_base = 0x10000000, so while jumping to 'relocated' the following translation occurs:
segment_base + logical_addr = phys_addr => 0x10000000 + 0xF010.... = (we expect 0x0010....)
In x86 machine it worked well, probably because the carried out '1' at the addition of 0xF........ and 0x1......... simply ignored (since it's "32th bit" of 31:0 address).
But in x86_64 machine qemu yields fatal error with attempt to access 0x00000001|0010.... which is above 4GB. The carried out "32th" '1' is not ignored but attached to physical address.
Ideas?
As in a segmentation fault (which is not a QEMU mechanism)? If that's the case, it's not your fault. Which host OS are you using?
Qemu is running on Ubuntu 10.04, which in turn runs in VMplayer, if it matters.

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 11:08 am
by Velko
I can confirm that Higher Half GDT trick does not work on recent qemu-system-x86_64 versions. Addresses do not wrap around when they should (running in Protected Mode). It looks like they broke it somewhere between versions 0.9.1 and 0.12.5. I noticed it when I upgraded my Debian development box to current stable release.

Workaround? Well, I switched to linear GDT and enable Paging earlier in booting process.

In a retrospect, it made much of my paging-initialization "ugliness" to go away. Also it enabled me to use most of my C code for both 32- and 64-bit kernels (before then my 64-bit kernel was unworkable mess). So actually I'm glad QEMU had that bug - it made me to step back and look for (as it turns out - better) alternatives.

Re: 32bit OS and qemu-system-x86_64

Posted: Fri Sep 23, 2011 11:28 am
by TryHarder
Velko wrote:I can confirm that Higher Half GDT trick does not work on recent qemu-system-x86_64 versions. Addresses do not wrap around when they should (running in Protected Mode). It looks like they broke it somewhere between versions 0.9.1 and 0.12.5. I noticed it when I upgraded my Debian development box to current stable release.

Workaround? Well, I switched to linear GDT and enable Paging earlier in booting process.

In a retrospect, it made much of my paging-initialization "ugliness" to go away. Also it enabled me to use most of my C code for both 32- and 64-bit kernels (before then my 64-bit kernel was unworkable mess). So actually I'm glad QEMU had that bug - it made me to step back and look for (as it turns out - better) alternatives.
Thanks in advance for your response, now things are clear for me. Solved!

Re: 32bit OS and qemu-system-x86_64

Posted: Sat Sep 24, 2011 4:29 pm
by wolfwood
[ur]http://wiki.xomb.org/index.php?title=XOmB_Bare_Bones[/url]

code and documentation for 32-bit and 64-bit boot process.