[prefix] Use flat real mode instead of real mode
authorMichael Brown <mcb30@ipxe.org>
Mon, 19 Apr 2010 20:53:36 +0000 (21:53 +0100)
committerStefan Hajnoczi <stefanha@gmail.com>
Wed, 7 Jul 2010 19:14:36 +0000 (20:14 +0100)
When returning to real mode, set 4GB segment limits instead of 64kB
limits.  This change improves our chances of successfully returning to
a PMM-capable BIOS aftering entering gPXE during POST; the BIOS will
have set up flat real mode before calling our initialisation point,
and may be disconcerted if we then return in genuine real mode.

This change is unlikely to break anything, since any code that might
potentially access beyond 64kB must use addr32 prefixes to do so; if
this is the case then it is almost certainly code written to expect
flat real mode anyway.

Note that it is not possible to restore the real-mode segment limits
to their original values, since it is not possible to know which
protected-mode segment descriptor was originally used to initialise
the limit portion of the segment register.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
src/arch/i386/prefix/libprefix.S
src/arch/i386/transitions/librm.S

index 9e6ba6f..ecef56d 100644 (file)
@@ -263,14 +263,14 @@ gdt:
 gdt_limit:             .word gdt_length - 1
 gdt_base:              .long 0
                        .word 0 /* padding */
 gdt_limit:             .word gdt_length - 1
 gdt_base:              .long 0
                        .word 0 /* padding */
-pm_cs:         /* 16-bit protected-mode code segment */        
+pm_cs:         /* 16-bit protected-mode flat code segment */
        .equ    PM_CS, pm_cs - gdt
        .word   0xffff, 0
        .equ    PM_CS, pm_cs - gdt
        .word   0xffff, 0
-       .byte   0, 0x9b, 0x00, 0
-pm_ss:         /* 16-bit protected-mode stack segment */
+       .byte   0, 0x9b, 0x8f, 0
+pm_ss:         /* 16-bit protected-mode flat stack segment */
        .equ    PM_SS, pm_ss - gdt
        .word   0xffff, 0
        .equ    PM_SS, pm_ss - gdt
        .word   0xffff, 0
-       .byte   0, 0x93, 0x00, 0
+       .byte   0, 0x93, 0x8f, 0
 pm_ds:         /* 32-bit protected-mode flat data segment */
        .equ    PM_DS, pm_ds - gdt
        .word   0xffff, 0
 pm_ds:         /* 32-bit protected-mode flat data segment */
        .equ    PM_DS, pm_ds - gdt
        .word   0xffff, 0
index cb27ef3..a07ffc5 100644 (file)
@@ -28,9 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER )
  * Call init_librm to set up the GDT before attempting to use any
  * protected-mode code.
  *
  * Call init_librm to set up the GDT before attempting to use any
  * protected-mode code.
  *
- * Define FLATTEN_REAL_MODE if you want to use so-called "flat real
- * mode" with 4GB limits instead.
- *
  * NOTE: This must be located before prot_to_real, otherwise gas
  * throws a "can't handle non absolute segment in `ljmp'" error due to
  * not knowing the value of REAL_CS when the ljmp is encountered.
  * NOTE: This must be located before prot_to_real, otherwise gas
  * throws a "can't handle non absolute segment in `ljmp'" error due to
  * not knowing the value of REAL_CS when the ljmp is encountered.
@@ -40,12 +37,6 @@ FILE_LICENCE ( GPL2_OR_LATER )
  * "non absolute segment" error.  This is most probably a bug in gas.
  ****************************************************************************
  */
  * "non absolute segment" error.  This is most probably a bug in gas.
  ****************************************************************************
  */
-       
-#ifdef FLATTEN_REAL_MODE
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x8f
-#else
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
-#endif
        .section ".data16", "aw", @progbits
        .align 16
 gdt:
        .section ".data16", "aw", @progbits
        .align 16
 gdt:
@@ -75,14 +66,14 @@ physical_ds:        /* 32 bit protected mode data segment, physical addresses */
        .byte   0, 0x93, 0xcf, 0        
 
        .org    gdt + REAL_CS, 0
        .byte   0, 0x93, 0xcf, 0        
 
        .org    gdt + REAL_CS, 0
-real_cs:       /* 16 bit real mode code segment */
+real_cs:       /* 16 bit flat real mode code segment */
        .word   0xffff, 0
        .word   0xffff, 0
-       .byte   0, 0x9b, RM_LIMIT_16_19__AVL__SIZE__GRANULARITY, 0
+       .byte   0, 0x9b, 0x8f, 0
 
        .org    gdt + REAL_DS   
 
        .org    gdt + REAL_DS   
-real_ds:       /* 16 bit real mode data segment */
+real_ds:       /* 16 bit flat real mode data segment */
        .word   0xffff, 0
        .word   0xffff, 0
-       .byte   0, 0x93, RM_LIMIT_16_19__AVL__SIZE__GRANULARITY, 0
+       .byte   0, 0x93, 0x8f, 0
        
 gdt_end:
        .equ    gdt_length, gdt_end - gdt
        
 gdt_end:
        .equ    gdt_length, gdt_end - gdt