switch IA-32e mode back to protected mode

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.
Post Reply
kaiven
Posts: 3
Joined: Thu Jul 09, 2009 8:31 pm

switch IA-32e mode back to protected mode

Post by kaiven »

Hi, everyone,

I am trying to switch IA-32e(64-bit sub mode) back to protected mode. I do it as Intel's manual says. but it fails at lretq. who knows the similar reason? this is my code. thank you.

Code: Select all

/*
        void switch_to_protected_mode(unsigned long rip,unsigned long rsi,unsigned long legacy_cr3)
*/
        //rdi,rsi,rdx,rcx,r8,r9
        .global switch_to_protected_mode
switch_to_protected_mode:
        mov %rdi,%rcx   /*rcx,target address*/
                /*1.switch to compatibility mode*/
                pushq $(__HYPERVISOR_CS32) //CS.L ==0, 
                leaq 1f(%rip),%rax
                pushq %rax
                lretq
1:
//self: jmp self
                /*2.deactive IA-32e mode by clear CR0.PG*/
                mov %cr0,%rax
                and $0x7fffffff,%rax
                mov %rax,%cr0
//self: jmp self
                /*3.load cr3 with legency page table*/
                mov %rdx,%cr3
                mov %rcx,%rdx
                /*4.disable IA-32e mode by setting IA32_EFER.LME*/
                mov $MSR_EFER,%rcx
                rdmsr
                btrl $_EFER_LME,%eax /*clear LME*/
                wrmsr
                /*5.enable legacy paged-protected mode by setting CR0.PG=1*/

/*              mov %cr0,%rax
                orl     $0x80000000,%eax
                mov %rax,%cr0
*/

//self: jmp self
                /*6.branch to instructions in protected mode*/
        jmp *%rdi
Last edited by 01000101 on Thu Jul 09, 2009 9:25 pm, edited 1 time in total.
Reason: added code tags
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: switch IA-32e mode back to protected mode

Post by Brendan »

Hi,

To me, it looks like the lretq should work (but "pushq 1f" should also work, avoiding the need for the "leaq").

However, everything after the lretq was assembled as 64-bit code, and it'll be running in a 32-bit code segment, which is likely to cause some serious problems. You'd need to use the equivalent of NASM's "bits 32" directive just before the "1:" to tell the assembler to start generating 32-bit code (to suit the 32-bit code segment), and then change everything to use instructions that are supported in 32-bit code (e.g. "mov %cr0,%eax", "and $0x7fffffff,%eax", etc).

I was curious, so I decompiled 5 lines after the "RETQ to 32-bit" to see what the CPU would think the instructions are. Here's the result:

Code: Select all

   0:   0f 20 c0                mov    %cr0,%eax
   3:   48                      dec    %eax
   4:   25 ff ff ff 7f          and    $0x7fffffff,%eax
   9:   0f 22 c0                mov    %eax,%cr0
   c:   0f 22 da                mov    %edx,%cr3
   f:   48                      dec    %eax
  10:   89 ca                   mov    %ecx,%edx
The "dec %eax" instructions would have been a REX prefixes if the CPU was running 64-bit code. The first "dec %eax" instruction would cause the "protected mode enable" flag in CR0 to be cleared.

Note: I took a look at the AS manual. There are command line options ("--32" and "--64"), but I failed to find any assembler directives to control the intended operating mode. I tried ".arch generic32" but that didn't change the code to 32-bit code (and didn't complain about 64-bit instructions not being supported on 32-bit CPUs either). I'm not sure how you'd get around this - maybe you could assemble 2 separate source files (one with 32-bit code and the other with 64-bit code) into object files, and then link these object files together? I'm not sure if the linker (and the object file format you're using) will like this idea, but if you're lucky you might be able to add a ".text32" section in your linker script and get it working.


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.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: switch IA-32e mode back to protected mode

Post by Combuster »

GAS is unable to assemble for any two operating modes at the same time - you will have to use NASM / YASM, or split up your code into several compilation units.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Re: switch IA-32e mode back to protected mode

Post by Brynet-Inc »

Combuster wrote:GAS is unable to assemble for any two operating modes at the same time - you will have to use NASM / YASM, or split up your code into several compilation units.
Forget about the .code{16,32,64} directives?
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: switch IA-32e mode back to protected mode

Post by Combuster »

That wasn't always the case. Google shows lists of mailing list messages about assembling 32 bit code, but no reference at all to the manuals. (which imnsho is a recurring problem with the whole lot of RMS tools)

Oh well, relevant post from the GCC mailing list discussing the annoyances of GAS:
> Or, if GAS can be told which mode it should be in via directives in
> its input (.code32/.code64?), then we could add something like
>
> fputs (TARGET_64BIT ? "\t.code64\n" : "\t.code32",
> asm_out_file);
>
> to x86_file_start, and kill the spec hackery altogether.

I'm a fan of such directives. I suspect that we'll have to keep
the spec hackery for a while yet. We don't usually force binutils
upgrades with compiler upgrades...
I'll be happy to believe that the latest GAS is free of these annoyances though.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: switch IA-32e mode back to protected mode

Post by Brendan »

Hi,

Doh - the documentation is incomplete.

I tested it on "GNU assembler version 2.18 (x86_64-pc-linux-gnu) using BFD version (GNU Binutils) 2.18". The ".code32" directive does work in 64-bit code, and the assembler does complain about the use of 64-bit general registers in 32-bit code. :)


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.
kaiven
Posts: 3
Joined: Thu Jul 09, 2009 8:31 pm

Re: switch IA-32e mode back to protected mode

Post by kaiven »

hi, all, thank you for your attention.

I also write ASM code sequence to switch ia32e (64-bit mode)-> ia32e(compatibility mode) ->protected mode with paging. But it fails at the second stage (compatibility mode -> protected mode). The sequence is like:
1. Create x86_32 page table
2. Switch to compatibility mode
3. De-activate IA-32e mode by clearing CR0.PG,and disable PAE
4. Load cr3 with x86_32 page table
5. Disable IA-32e mode by setting IA32_EFER.LME
6. Enable legacy paging protected mode by setting CR0.PG=1
7. Switch GDTR, cs,ds,es,fs,gs,ss to x86_32 mode (failed.)
8. Jump to execute 1st instruction in protected mode.

p.s. this is source code, it is built on RHEL5U2 x64. its objdump code is after it. I don't know why lgdt failed when it tries to load GDT for protected mode.

Code: Select all

/*
         void nuc_switch_to_protected_mode(unsigned long rip,unsigned long rsi)
*/
         //rdi,rsi,rdx,rcx,r8,r9
        .global nuc_switch_to_protected_mode
nuc_switch_to_protected_mode:
    
                   mov %rdi,%rbx         /*rbx, target eip*/
         
                   /*create 32-bit page table: 1G 1:1 mapping, this switch code is also on the 1:1 mapping.*/
                   movl $(sym_phys(guest_pg)),%edi
                   movl $(sym_phys(legacy_pg_table)),%edx
                   movl $0x7,%eax
                   movl $0,%ebp
10:
                   leal 0x7(%edi),%ecx          /*create PDE entry*/
                   movl %ecx,(%edx)    /*store PDE entry*/
                   addl $4,%edx            /*increase PDE index*/
                   addl $1,%ebp
                   movl $1024,%ecx
11:
                   stosl
                   addl $0x1000,%eax
                   loop 11b
                   cmpl $256,%ebp
                   jne 10b     
                   
                   /*1.switch to compatibility mode*/
                   pushq $(__HYPERVISOR_CS32)
                   leaq enter_compability_mode(%rip),%rax
                   leaq enter_protected_mode(%rip),%rbp
                   pushq %rax
                   lretq

                   .code32
enter_compability_mode:
                   /*In compatibility now*/
                   /*2.deactive IA-32e mode by clear CR0.PG*/          
                   mov %cr0,%eax
                   and $0x7fffffff,%eax
                   mov %eax,%cr0
                   /*disable PAE*/
                   mov %cr4,%eax
                   and $0xffffffdf,%eax         /*clear PAE,bit 5*/
                   mov %eax,%cr4
                   /*3.load cr3 with legency page table*/
                   mov $(sym_phys(legacy_pg_table)),%eax
                   mov %eax,%cr3
                   /*4.disable IA-32e mode by setting IA32_EFER.LME*/
                   mov $MSR_EFER,%ecx
                   rdmsr
                   btrl $_EFER_LME,%eax /*clear LME*/
                   wrmsr
                   /*5.enable legacy paged-protected mode by setting CR0.PG=1*/
                   mov %cr0,%eax
                   orl    $0x80000000,%eax          
                   mov %eax,%cr0
         
                   /*setup guest's segmentation in protected mode*/
                   /*BUG: Here*/
                   lgdt sym_phys(guest_boot_gdt_descr)   //it fails here.
                   movl $GUEST_BOOT_DS,%eax
                   movl %eax,%gs
                   movl %eax,%ss
                   movl %eax,%fs
                   movl %eax,%ds
                   movl %eax,%es
         
                   push $GUEST_BOOT_CS
                   push %ebp /*High 32-bit is truncted.*/
                   iret
enter_protected_mode:
                   /*6.branch to instructions in protected mode*/
        jmp *%ebx
                   ret
the dumping code is:

Code: Select all

ffffc10028119084 <switch_to_protected_mode>:
ffffc10028119084:	48 89 fb             	mov    %rdi,%rbx
ffffc10028119087:	bf 00 90 00 28       	mov    $0x28009000,%edi
ffffc1002811908c:	ba 00 80 00 28       	mov    $0x28008000,%edx
ffffc10028119091:	b8 07 00 00 00       	mov    $0x7,%eax
ffffc10028119096:	bd 00 00 00 00       	mov    $0x0,%ebp
ffffc1002811909b:	67 8d 4f 07          	addr32 lea 0x7(%edi),%ecx
ffffc1002811909f:	67 89 0a             	addr32 mov %ecx,(%edx)
ffffc100281190a2:	83 c2 04             	add    $0x4,%edx
ffffc100281190a5:	83 c5 01             	add    $0x1,%ebp
ffffc100281190a8:	b9 00 04 00 00       	mov    $0x400,%ecx
ffffc100281190ad:	ab                   	stos   %eax,%es:(%rdi)
ffffc100281190ae:	05 00 10 00 00       	add    $0x1000,%eax
ffffc100281190b3:	e2 f8                	loop   ffffc100281190ad <switch_to_protected_mode+0x29>
ffffc100281190b5:	81 fd 00 01 00 00    	cmp    $0x100,%ebp
ffffc100281190bb:	75 de                	jne    ffffc1002811909b <switch_to_protected_mode+0x17>
ffffc100281190bd:	68 38 e0 00 00       	pushq  $0xe038
ffffc100281190c2:	48 8d 05 0a 00 00 00 	lea    10(%rip),%rax        # ffffc100281190d3 <enter_compability_mode>
ffffc100281190c9:	48 8d 2d 51 00 00 00 	lea    81(%rip),%rbp        # ffffc10028119121 <enter_protected_mode>
ffffc100281190d0:	50                   	push   %rax
ffffc100281190d1:	48 cb                	lretq  

ffffc100281190d3 <enter_compability_mode>:
ffffc100281190d3:	0f 20 c0             	mov    %cr0,%rax
ffffc100281190d6:	25 ff ff ff 7f       	and    $0x7fffffff,%eax
ffffc100281190db:	0f 22 c0             	mov    %rax,%cr0
ffffc100281190de:	0f 20 e0             	mov    %cr4,%rax
ffffc100281190e1:	83 e0 df             	and    $0xffffffffffffffdf,%eax
ffffc100281190e4:	0f 22 e0             	mov    %rax,%cr4
ffffc100281190e7:	b8 00 80 00 28       	mov    $0x28008000,%eax
ffffc100281190ec:	0f 22 d8             	mov    %rax,%cr3
ffffc100281190ef:	b9 80 00 00 c0       	mov    $0xc0000080,%ecx
ffffc100281190f4:	0f 32                	rdmsr  
ffffc100281190f6:	0f ba f0 08          	btr    $0x8,%eax
ffffc100281190fa:	0f 30                	wrmsr  
ffffc100281190fc:	0f 20 c0             	mov    %cr0,%rax
ffffc100281190ff:	0d 00 00 00 80       	or     $0x80000000,%eax
ffffc10028119104:	0f 22 c0             	mov    %rax,%cr0
ffffc10028119107:	0f 01 15 02 90 10 28 	lgdt   672174082(%rip)        # ffffc10050222110 <_end+0x27f9d800> ///failed here.
ffffc1002811910e:	b8 18 00 00 00       	mov    $0x18,%eax
ffffc10028119113:	8e e8                	movl   %eax,%gs
ffffc10028119115:	8e d0                	movl   %eax,%ss
ffffc10028119117:	8e e0                	movl   %eax,%fs
ffffc10028119119:	8e d8                	movl   %eax,%ds
ffffc1002811911b:	8e c0                	movl   %eax,%es
ffffc1002811911d:	6a 10                	pushq  $0x10
ffffc1002811911f:	55                   	push   %rbp
ffffc10028119120:	cf                   	iret 

Code: Select all

ENTRY(legacy_pg_table)
         .fill 1024,4,0

/*1:1 mapping in 1G*/
#define GUEST_MAP_END 1024*1024*1024
ENTRY(guest_pg)
         .fill 1024*256,4,0

#define GUEST_GDT_ENTRY_BOOT_CS 2
#define GUEST_BOOT_CS (GUEST_GDT_ENTRY_BOOT_CS*8)

#define GUEST_GDT_ENTRY_BOOT_DS (GUEST_GDT_ENTRY_BOOT_CS + 1)
#define GUEST_BOOT_DS (GUEST_GDT_ENTRY_BOOT_DS*8)

# early boot GDT descriptor (must use 1:1 address mapping)
         .word 0                                # 32 bit align gdt_desc.address
guest_boot_gdt_descr:
         .word 16*4096
         .long sym_phys(guest_boot_gdt_table)

/*
 * The boot_gdt_table must mirror the equivalent in setup.S and is
 * used only for booting.
 */
         .align 128
ENTRY(guest_boot_gdt_table)
         .quad 0x0000000000000000    /* 0x0 unused */
         .quad 0x0000000000000000    /* 0x8 unused */
         .quad 0x00cf9a000000ffff        /* 0x10 GUEST_BOOT_CS:       kernel 4GB code at 0x00000000 */
         .quad 0x00cf92000000ffff        /* 0x18 GUEST_BOOT_DS:      kernel 4GB data at 0x00000000 */
         .fill FIRST_RESERVED_GDT_ENTRY-4,8,0
         .quad 0x0000000000000000    /* unused */
    .quad 0x00af9a000000ffff    /* 0xe008 ring 0 code, 64-bit mode   */
    .quad 0x00cf92000000ffff    /* 0xe010 ring 0 data                */
    .quad 0x0000000000000000    /* reserved                          */
    .quad 0x00cffa000000ffff    /* 0xe023 ring 3 code, compatibility */
    .quad 0x00cff2000000ffff    /* 0xe02b ring 3 data                */
    .quad 0x00affa000000ffff    /* 0xe033 ring 3 code, 64-bit mode   */
         .quad 0x00cf9a000000ffff    /* (HYPERVISOR_CS32)0xe038 ring 0 code, compatibility */
Last edited by quok on Mon Jul 13, 2009 8:22 am, edited 1 time in total.
Reason: Fixed to not break forum rule 6.
kaiven
Posts: 3
Joined: Thu Jul 09, 2009 8:31 pm

Re: switch IA-32e mode back to protected mode

Post by kaiven »

latest update.
after debugging, when add instruction when entering compatibility mode.
movl $__HYPERVISOR_DS32,%eax
movl %eax,%gs
movl %eax,%ss
movl %eax,%fs
movl %eax,%ds
movl %eax,%es

the following lgdt pass, but movl to gs failed.

lgdt sym_phys(guest_boot_gdt_descr) //it fails here.
movl $GUEST_BOOT_DS,%eax
movl %eax,%gs
kaiven wrote:hi, all, thank you for your attention.

I also write ASM code sequence to switch ia32e (64-bit mode)-> ia32e(compatibility mode) ->protected mode with paging. But it fails at the second stage (compatibility mode -> protected mode). The sequence is like:
1. Create x86_32 page table
2. Switch to compatibility mode
3. De-activate IA-32e mode by clearing CR0.PG,and disable PAE
4. Load cr3 with x86_32 page table
5. Disable IA-32e mode by setting IA32_EFER.LME
6. Enable legacy paging protected mode by setting CR0.PG=1
7. Switch GDTR, cs,ds,es,fs,gs,ss to x86_32 mode (failed.)
8. Jump to execute 1st instruction in protected mode.

p.s. this is source code, it is built on RHEL5U2 x64. its objdump code is after it. I don't know why lgdt failed when it tries to load GDT for protected mode.

Code: Select all

/*
         void nuc_switch_to_protected_mode(unsigned long rip,unsigned long rsi)
*/
         //rdi,rsi,rdx,rcx,r8,r9
        .global nuc_switch_to_protected_mode
nuc_switch_to_protected_mode:
    
                   mov %rdi,%rbx         /*rbx, target eip*/
         
                   /*create 32-bit page table: 1G 1:1 mapping, this switch code is also on the 1:1 mapping.*/
                   movl $(sym_phys(guest_pg)),%edi
                   movl $(sym_phys(legacy_pg_table)),%edx
                   movl $0x7,%eax
                   movl $0,%ebp
10:
                   leal 0x7(%edi),%ecx          /*create PDE entry*/
                   movl %ecx,(%edx)    /*store PDE entry*/
                   addl $4,%edx            /*increase PDE index*/
                   addl $1,%ebp
                   movl $1024,%ecx
11:
                   stosl
                   addl $0x1000,%eax
                   loop 11b
                   cmpl $256,%ebp
                   jne 10b     
                   
                   /*1.switch to compatibility mode*/
                   pushq $(__HYPERVISOR_CS32)
                   leaq enter_compability_mode(%rip),%rax
                   leaq enter_protected_mode(%rip),%rbp
                   pushq %rax
                   lretq

                   .code32
enter_compability_mode:
                   /*In compatibility now*/
                   /*2.deactive IA-32e mode by clear CR0.PG*/          
                   mov %cr0,%eax
                   and $0x7fffffff,%eax
                   mov %eax,%cr0
                   /*disable PAE*/
                   mov %cr4,%eax
                   and $0xffffffdf,%eax         /*clear PAE,bit 5*/
                   mov %eax,%cr4
                   /*3.load cr3 with legency page table*/
                   mov $(sym_phys(legacy_pg_table)),%eax
                   mov %eax,%cr3
                   /*4.disable IA-32e mode by setting IA32_EFER.LME*/
                   mov $MSR_EFER,%ecx
                   rdmsr
                   btrl $_EFER_LME,%eax /*clear LME*/
                   wrmsr
                   /*5.enable legacy paged-protected mode by setting CR0.PG=1*/
                   mov %cr0,%eax
                   orl    $0x80000000,%eax          
                   mov %eax,%cr0
         
                   /*setup guest's segmentation in protected mode*/
                   /*BUG: Here*/
                   lgdt sym_phys(guest_boot_gdt_descr)   //it fails here.
                   movl $GUEST_BOOT_DS,%eax
                   movl %eax,%gs
                   movl %eax,%ss
                   movl %eax,%fs
                   movl %eax,%ds
                   movl %eax,%es
         
                   push $GUEST_BOOT_CS
                   push %ebp /*High 32-bit is truncted.*/
                   iret
enter_protected_mode:
                   /*6.branch to instructions in protected mode*/
        jmp *%ebx
                   ret
the dumping code is:

Code: Select all

ffffc10028119084 <switch_to_protected_mode>:
ffffc10028119084:	48 89 fb             	mov    %rdi,%rbx
ffffc10028119087:	bf 00 90 00 28       	mov    $0x28009000,%edi
ffffc1002811908c:	ba 00 80 00 28       	mov    $0x28008000,%edx
ffffc10028119091:	b8 07 00 00 00       	mov    $0x7,%eax
ffffc10028119096:	bd 00 00 00 00       	mov    $0x0,%ebp
ffffc1002811909b:	67 8d 4f 07          	addr32 lea 0x7(%edi),%ecx
ffffc1002811909f:	67 89 0a             	addr32 mov %ecx,(%edx)
ffffc100281190a2:	83 c2 04             	add    $0x4,%edx
ffffc100281190a5:	83 c5 01             	add    $0x1,%ebp
ffffc100281190a8:	b9 00 04 00 00       	mov    $0x400,%ecx
ffffc100281190ad:	ab                   	stos   %eax,%es:(%rdi)
ffffc100281190ae:	05 00 10 00 00       	add    $0x1000,%eax
ffffc100281190b3:	e2 f8                	loop   ffffc100281190ad <switch_to_protected_mode+0x29>
ffffc100281190b5:	81 fd 00 01 00 00    	cmp    $0x100,%ebp
ffffc100281190bb:	75 de                	jne    ffffc1002811909b <switch_to_protected_mode+0x17>
ffffc100281190bd:	68 38 e0 00 00       	pushq  $0xe038
ffffc100281190c2:	48 8d 05 0a 00 00 00 	lea    10(%rip),%rax        # ffffc100281190d3 <enter_compability_mode>
ffffc100281190c9:	48 8d 2d 51 00 00 00 	lea    81(%rip),%rbp        # ffffc10028119121 <enter_protected_mode>
ffffc100281190d0:	50                   	push   %rax
ffffc100281190d1:	48 cb                	lretq  

ffffc100281190d3 <enter_compability_mode>:
ffffc100281190d3:	0f 20 c0             	mov    %cr0,%rax
ffffc100281190d6:	25 ff ff ff 7f       	and    $0x7fffffff,%eax
ffffc100281190db:	0f 22 c0             	mov    %rax,%cr0
ffffc100281190de:	0f 20 e0             	mov    %cr4,%rax
ffffc100281190e1:	83 e0 df             	and    $0xffffffffffffffdf,%eax
ffffc100281190e4:	0f 22 e0             	mov    %rax,%cr4
ffffc100281190e7:	b8 00 80 00 28       	mov    $0x28008000,%eax
ffffc100281190ec:	0f 22 d8             	mov    %rax,%cr3
ffffc100281190ef:	b9 80 00 00 c0       	mov    $0xc0000080,%ecx
ffffc100281190f4:	0f 32                	rdmsr  
ffffc100281190f6:	0f ba f0 08          	btr    $0x8,%eax
ffffc100281190fa:	0f 30                	wrmsr  
ffffc100281190fc:	0f 20 c0             	mov    %cr0,%rax
ffffc100281190ff:	0d 00 00 00 80       	or     $0x80000000,%eax
ffffc10028119104:	0f 22 c0             	mov    %rax,%cr0
ffffc10028119107:	0f 01 15 02 90 10 28 	lgdt   672174082(%rip)        # ffffc10050222110 <_end+0x27f9d800> ///failed here.
ffffc1002811910e:	b8 18 00 00 00       	mov    $0x18,%eax
ffffc10028119113:	8e e8                	movl   %eax,%gs
ffffc10028119115:	8e d0                	movl   %eax,%ss
ffffc10028119117:	8e e0                	movl   %eax,%fs
ffffc10028119119:	8e d8                	movl   %eax,%ds
ffffc1002811911b:	8e c0                	movl   %eax,%es
ffffc1002811911d:	6a 10                	pushq  $0x10
ffffc1002811911f:	55                   	push   %rbp
ffffc10028119120:	cf                   	iret 

Code: Select all

ENTRY(legacy_pg_table)
         .fill 1024,4,0

/*1:1 mapping in 1G*/
#define GUEST_MAP_END 1024*1024*1024
ENTRY(guest_pg)
         .fill 1024*256,4,0

#define GUEST_GDT_ENTRY_BOOT_CS 2
#define GUEST_BOOT_CS (GUEST_GDT_ENTRY_BOOT_CS*8)

#define GUEST_GDT_ENTRY_BOOT_DS (GUEST_GDT_ENTRY_BOOT_CS + 1)
#define GUEST_BOOT_DS (GUEST_GDT_ENTRY_BOOT_DS*8)

# early boot GDT descriptor (must use 1:1 address mapping)
         .word 0                                # 32 bit align gdt_desc.address
guest_boot_gdt_descr:
         .word 16*4096
         .long sym_phys(guest_boot_gdt_table)

/*
 * The boot_gdt_table must mirror the equivalent in setup.S and is
 * used only for booting.
 */
         .align 128
ENTRY(guest_boot_gdt_table)
         .quad 0x0000000000000000    /* 0x0 unused */
         .quad 0x0000000000000000    /* 0x8 unused */
         .quad 0x00cf9a000000ffff        /* 0x10 GUEST_BOOT_CS:       kernel 4GB code at 0x00000000 */
         .quad 0x00cf92000000ffff        /* 0x18 GUEST_BOOT_DS:      kernel 4GB data at 0x00000000 */
         .fill FIRST_RESERVED_GDT_ENTRY-4,8,0
         .quad 0x0000000000000000    /* unused */
    .quad 0x00af9a000000ffff    /* 0xe008 ring 0 code, 64-bit mode   */
    .quad 0x00cf92000000ffff    /* 0xe010 ring 0 data                */
    .quad 0x0000000000000000    /* reserved                          */
    .quad 0x00cffa000000ffff    /* 0xe023 ring 3 code, compatibility */
    .quad 0x00cff2000000ffff    /* 0xe02b ring 3 data                */
    .quad 0x00affa000000ffff    /* 0xe033 ring 3 code, 64-bit mode   */
         .quad 0x00cf9a000000ffff    /* (HYPERVISOR_CS32)0xe038 ring 0 code, compatibility */
Last edited by quok on Mon Jul 13, 2009 8:24 am, edited 1 time in total.
Reason: Fixed to not break forum rule 6.
Post Reply