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.
32bit OS and qemu-system-x86_64
Re: 32bit OS and qemu-system-x86_64
Right. Mine works fine.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?
Your code.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)?
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: 32bit OS and qemu-system-x86_64
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?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?
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?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)?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: 32bit OS and qemu-system-x86_64
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 ).
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
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
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?
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
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?
Qemu is running on Ubuntu 10.04, which in turn runs in VMplayer, if it matters.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?
Last edited by TryHarder on Fri Sep 23, 2011 1:30 pm, edited 1 time in total.
Re: 32bit OS and qemu-system-x86_64
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.
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.
If something looks overcomplicated, most likely it is.
Re: 32bit OS and qemu-system-x86_64
Thanks in advance for your response, now things are clear for me. Solved!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.
Re: 32bit OS and qemu-system-x86_64
[ur]http://wiki.xomb.org/index.php?title=XOmB_Bare_Bones[/url]
code and documentation for 32-bit and 64-bit boot process.
code and documentation for 32-bit and 64-bit boot process.