Browse Source

[prefix] Use flat real mode instead of real mode

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 iPXE 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>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
cb43056809
2 changed files with 8 additions and 17 deletions
  1. 4
    4
      src/arch/i386/prefix/libprefix.S
  2. 4
    13
      src/arch/i386/transitions/librm.S

+ 4
- 4
src/arch/i386/prefix/libprefix.S View File

263
 gdt_limit:		.word gdt_length - 1
263
 gdt_limit:		.word gdt_length - 1
264
 gdt_base:		.long 0
264
 gdt_base:		.long 0
265
 			.word 0 /* padding */
265
 			.word 0 /* padding */
266
-pm_cs:		/* 16-bit protected-mode code segment */	
266
+pm_cs:		/* 16-bit protected-mode flat code segment */
267
 	.equ    PM_CS, pm_cs - gdt
267
 	.equ    PM_CS, pm_cs - gdt
268
 	.word   0xffff, 0
268
 	.word   0xffff, 0
269
-	.byte   0, 0x9b, 0x00, 0
270
-pm_ss:		/* 16-bit protected-mode stack segment */
269
+	.byte   0, 0x9b, 0x8f, 0
270
+pm_ss:		/* 16-bit protected-mode flat stack segment */
271
 	.equ    PM_SS, pm_ss - gdt
271
 	.equ    PM_SS, pm_ss - gdt
272
 	.word   0xffff, 0
272
 	.word   0xffff, 0
273
-	.byte   0, 0x93, 0x00, 0
273
+	.byte   0, 0x93, 0x8f, 0
274
 pm_ds:		/* 32-bit protected-mode flat data segment */
274
 pm_ds:		/* 32-bit protected-mode flat data segment */
275
 	.equ    PM_DS, pm_ds - gdt
275
 	.equ    PM_DS, pm_ds - gdt
276
 	.word   0xffff, 0
276
 	.word   0xffff, 0

+ 4
- 13
src/arch/i386/transitions/librm.S View File

28
  * Call init_librm to set up the GDT before attempting to use any
28
  * Call init_librm to set up the GDT before attempting to use any
29
  * protected-mode code.
29
  * protected-mode code.
30
  *
30
  *
31
- * Define FLATTEN_REAL_MODE if you want to use so-called "flat real
32
- * mode" with 4GB limits instead.
33
- *
34
  * NOTE: This must be located before prot_to_real, otherwise gas
31
  * NOTE: This must be located before prot_to_real, otherwise gas
35
  * throws a "can't handle non absolute segment in `ljmp'" error due to
32
  * throws a "can't handle non absolute segment in `ljmp'" error due to
36
  * not knowing the value of REAL_CS when the ljmp is encountered.
33
  * not knowing the value of REAL_CS when the ljmp is encountered.
40
  * "non absolute segment" error.  This is most probably a bug in gas.
37
  * "non absolute segment" error.  This is most probably a bug in gas.
41
  ****************************************************************************
38
  ****************************************************************************
42
  */
39
  */
43
-	
44
-#ifdef FLATTEN_REAL_MODE
45
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x8f
46
-#else
47
-#define RM_LIMIT_16_19__AVL__SIZE__GRANULARITY 0x00
48
-#endif
49
 	.section ".data16", "aw", @progbits
40
 	.section ".data16", "aw", @progbits
50
 	.align 16
41
 	.align 16
51
 gdt:
42
 gdt:
75
 	.byte	0, 0x93, 0xcf, 0	
66
 	.byte	0, 0x93, 0xcf, 0	
76
 
67
 
77
 	.org	gdt + REAL_CS, 0
68
 	.org	gdt + REAL_CS, 0
78
-real_cs: 	/* 16 bit real mode code segment */
69
+real_cs: 	/* 16 bit flat real mode code segment */
79
 	.word	0xffff, 0
70
 	.word	0xffff, 0
80
-	.byte	0, 0x9b, RM_LIMIT_16_19__AVL__SIZE__GRANULARITY, 0
71
+	.byte	0, 0x9b, 0x8f, 0
81
 
72
 
82
 	.org	gdt + REAL_DS	
73
 	.org	gdt + REAL_DS	
83
-real_ds:	/* 16 bit real mode data segment */
74
+real_ds:	/* 16 bit flat real mode data segment */
84
 	.word	0xffff, 0
75
 	.word	0xffff, 0
85
-	.byte	0, 0x93, RM_LIMIT_16_19__AVL__SIZE__GRANULARITY, 0
76
+	.byte	0, 0x93, 0x8f, 0
86
 	
77
 	
87
 gdt_end:
78
 gdt_end:
88
 	.equ	gdt_length, gdt_end - gdt
79
 	.equ	gdt_length, gdt_end - gdt

Loading…
Cancel
Save