32 bit OS support on x86-64 architecture

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.
cianfa72
Member
Member
Posts: 73
Joined: Sat Dec 22, 2012 12:01 pm

32 bit OS support on x86-64 architecture

Post by cianfa72 »

Hi,

reading x86-64 processor specs I've learned about supported modes: Long mode and Legacy mode

Now I suppose pure 32 bit OS (e.g. Linux/Windows 32 bit) use Legacy mode (i.e. starting from real mode and then switching to protected mode)

How can I check this from a processor point of view when 32 bit OS is running ?

Thanks.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 32 bit OS support on x86-64 architecture

Post by bluemoon »

Checking CPUID for long mode support, then read the related MSR for LME(long mode enabled)
User avatar
iansjack
Member
Member
Posts: 4711
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: 32 bit OS support on x86-64 architecture

Post by iansjack »

Section 2.2 of Volume 3 of the Intel manual describes the different operating modes, how they are entered, and how you can use various registers to determine the current operating mode of the processor.
cianfa72
Member
Member
Posts: 73
Joined: Sat Dec 22, 2012 12:01 pm

Re: 32 bit OS support on x86-64 architecture

Post by cianfa72 »

bluemoon wrote:Checking CPUID for long mode support, then read the related MSR for LME(long mode enabled)
A call to CPUID returns longmode-capable-bit turned on in the EDX extended feature flags (bit 29) (http://wiki.osdev.org/X86-64):

Code: Select all

0:000> r edx
edx=28100000
0:000> .formats 28100000
Evaluate expression:
  Hex:     28100000
  Decimal: 672137216
  Octal:   05004000000
  Binary:  00101000 00010000 00000000 00000000 <-------------

now trying to assemble & execute

Code: Select all

	mov	$0xC0000080, %ecx
	rdmsr
I get an error...it seems the last instruction (rdmsr) has to be executed only at ring 0 privilege...(in other words the only way is run the code in kernel mode)

Can you confirm that ?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 32 bit OS support on x86-64 architecture

Post by bluemoon »

cianfa72 wrote: I get an error...it seems the last instruction (rdmsr) has to be executed only at ring 0 privilege...Can you confirm that ?
Yes, according the the manual:
#GP(0)
- If the current privilege level is not 0.
- If the value in ECX specifies a reserved or unimplemented MSR address.
cianfa72 wrote:in other words the only way is run the code in kernel mode
No, not necessary strictly "run in kernel" if I understand what you meant correctly, most general purpose OS provide some sort of mechanism to gain ring0 access (drivers, kernel extensions, special administrative APIs, etc).
Last edited by bluemoon on Mon Jan 21, 2013 8:13 am, edited 1 time in total.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: 32 bit OS support on x86-64 architecture

Post by Gigasoft »

Yes, RDMSR works only in kernel mode. On Windows, you can determine if you're running in long mode by calling GetNativeSystemInfo. If this function exists, and wProcessorArchitecture equals 9, then yes, otherwise no. On Linux I have no idea except perhaps calling the uname function and searching for "x64" in the returned string.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: 32 bit OS support on x86-64 architecture

Post by Antti »

Perhaps it could be tested by executing some normal instruction that behaves differently? Long mode is easy (e.g. push/pop) but what about Legacy Mode... Is it possible? Maybe not...
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: 32 bit OS support on x86-64 architecture

Post by Gigasoft »

I think you've got your terms mixed up, because that sentence doesn't make sense.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: 32 bit OS support on x86-64 architecture

Post by Brendan »

Hi,
Antti wrote:Perhaps it could be tested by executing some normal instruction that behaves differently? Long mode is easy (e.g. push/pop) but what about Legacy Mode... Is it possible? Maybe not...
For 64-bit code it's a compile-time problem rather than a run-time problem (if your 64-bit code is executing then you're in long mode).

For 16-bit and 32-bit code; to determine if you're running in protected mode or long mode there's no difference in the behaviour of different instructions (that I know of). However, I can't imagine an OS that doesn't use a 256-entry IDT, and IDT entries are larger in long mode (16 bytes instead of 8 bytes). This means that an application could do "SIDT" (which is allowed at CPL=3) and check the OS's IDT limit (e.g. "if(IDT_limit < 2048) { assume protected mode } else { assume long mode }"). Even though this isn't guaranteed to be foolproof, it's extremely likely that it'd work correctly on all OSs.

For real mode code, to determine if you're running in real mode or virtual8086 mode you can "pushf" and examine the VM flag.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: 32 bit OS support on x86-64 architecture

Post by Antti »

Gigasoft wrote:I think you've got your terms mixed up, because that sentence doesn't make sense.
Yes, my post did not help to solve the original problem. What I meant was something like this (ring-3 code):

Code: Select all

Carefully written x86 and x86-64 compatible code
Check (r/e)sp value and store it
Do push
Check (r/e)sp value and and compare

If difference is 4 jump to ProtectedModeCode:
If difference is 8 jump to LongModeCode:


ProtectedModeCode:
	do something

LongModeCode:
	do something
The main idea is that we could have a binary that could be executing in both Protected Mode and Long Mode (without requiring ring-0 privileges). I have not checked opcodes that I cannot say for sure whether that "push method and compare" works or not.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: 32 bit OS support on x86-64 architecture

Post by bluemoon »

If you want to detect the current bit mode, you can do the following:

Code: Select all

foo:
        db      0x48
        db      0xB8
        dd      0xdeadbeef
        db      0xEB
        db      123
        dw      0

This, when operate in 32-bit mode refer to:
 0:	48                   	dec    %eax
 1:	b8 ef be ad de       	mov    $0xdeadbeef,%eax
 6:	eb 7b                	jmp    83 <foo+0x83>
 8:	00 00                	add    %al,(%eax)

However, when operate in 64-bit mode it become:
   0:	48 b8 ef be ad de eb 	movabs $0x7bebdeadbeef,%rax
   7:	7b 00 00 

*Note that you need to change the jump offset for practical uses.
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: 32 bit OS support on x86-64 architecture

Post by rdos »

I think Brendans idea might work, but it cannot determine if long mode applications can execute, or the bitness of the kernel. All it does is to detect the current mode. For example in RDOS, it will always indicate "protected mode", because 32-bit applications always run in protected mode (at least until a processor without protected mode support exist).
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: 32 bit OS support on x86-64 architecture

Post by jnc100 »

As far as I understand, when most modern 64 bit operating systems are running on a 64 bit processor then the actual CPU mode used depends on the bitness of the executable file: for ELF64/PE64 long mode is used, else compatibility mode is used. This generally means you can't have one binary which works in both 32 or 64 bit mode depending on the bitness of the underlying OS, but instead need to compile the executable separately for both. In this sense, testing for long mode vs compatibility mode in code may be as simple as doing something like #ifdef _LP64 (for gcc). Obviously protected mode instead of compatibility mode would be used when a 32 bit OS is used.

Regards,
John.
cianfa72
Member
Member
Posts: 73
Joined: Sat Dec 22, 2012 12:01 pm

Re: 32 bit OS support on x86-64 architecture

Post by cianfa72 »

AFAIK the "main" CPU mode for a modern 64 bit OS running on a 64 bit processor is "long mode". This CPU mode supports 2 sub-modes: 64 bit mode and compatibility mode.
jnc100 wrote:As far as I understand, when most modern 64 bit operating systems are running on a 64 bit processor then the actual CPU mode used depends on the bitness of the executable file: for ELF64/PE64 long mode is used, else compatibility mode is used.
Here do you refer actually to the two possible long mode "sub-modes" ?
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: 32 bit OS support on x86-64 architecture

Post by rdos »

cianfa72 wrote:AFAIK the "main" CPU mode for a modern 64 bit OS running on a 64 bit processor is "long mode". This CPU mode supports 2 sub-modes: 64 bit mode and compatibility mode.
Actually, from the point of view of the processor, the switch to long mode basically does nothing. It switches from protected mode to compability mode, but the instructions are executed the same way. The actual switch to 64-bit mode is done by a far control transfer to a 64-bit code segment. The main difference between the protected mode and long mode environment is in interrupt and exception handlers, and the content (and size) of IDT.

It's also easy and relatively quick to switch between compability-mode and protected mode. The main time in this transition is the TLB flush.
Post Reply