Browse Source

Some operating systems get a nasty shock if a region of the E820 map seems

to start on a non-page boundary.  Make life safer by rounding out our
edited regions.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
aaed3d50a8
2 changed files with 80 additions and 43 deletions
  1. 77
    18
      src/arch/i386/firmware/pcbios/hidemem.c
  2. 3
    25
      src/include/gpxe/hidemem.h

+ 77
- 18
src/arch/i386/firmware/pcbios/hidemem.c View File

16
  */
16
  */
17
 
17
 
18
 #include <realmode.h>
18
 #include <realmode.h>
19
+#include <bios.h>
19
 #include <biosint.h>
20
 #include <biosint.h>
20
 #include <gpxe/hidemem.h>
21
 #include <gpxe/hidemem.h>
21
 
22
 
22
-/* Linker-defined symbols */
23
-extern char _text[];
24
-extern char _end[];
23
+/** Alignment for hidden memory regions */
24
+#define ALIGN_HIDDEN 4096   /* 4kB page alignment should be enough */
25
 
25
 
26
-/** Assembly routine in e820mangler.S */
27
-extern void int15();
28
-
29
-/** Vector for storing original INT 15 handler */
30
-extern struct segoff __text16 ( int15_vector );
31
-#define int15_vector __use_text16 ( int15_vector )
26
+/**
27
+ * A hidden region of Etherboot
28
+ *
29
+ * This represents a region that will be edited out of the system's
30
+ * memory map.
31
+ *
32
+ * This structure is accessed by assembly code, so must not be
33
+ * changed.
34
+ */
35
+struct hidden_region {
36
+	/* Physical start address */
37
+	physaddr_t start;
38
+	/* Physical end address */
39
+	physaddr_t end;
40
+};
32
 
41
 
33
 /**
42
 /**
34
  * List of hidden regions
43
  * List of hidden regions
37
  */
46
  */
38
 struct hidden_region __data16_array ( hidden_regions, [] ) = {
47
 struct hidden_region __data16_array ( hidden_regions, [] ) = {
39
 	[TEXT] = { 0, 0 },
48
 	[TEXT] = { 0, 0 },
40
-	[BASEMEM] = { 0, ( 640 * 1024 ) },
49
+	[BASEMEM] = { ( 640 * 1024 ), ( 640 * 1024 ) },
41
 	[EXTMEM] = { 0, 0 },
50
 	[EXTMEM] = { 0, 0 },
42
 	{ 0, 0, } /* Terminator */
51
 	{ 0, 0, } /* Terminator */
43
 };
52
 };
53
+#define hidden_regions __use_data16 ( hidden_regions )
54
+
55
+/** Assembly routine in e820mangler.S */
56
+extern void int15();
57
+
58
+/** Vector for storing original INT 15 handler */
59
+extern struct segoff __text16 ( int15_vector );
60
+#define int15_vector __use_text16 ( int15_vector )
61
+
62
+/**
63
+ * Hide region of memory from system memory map
64
+ *
65
+ * @v start		Start of region
66
+ * @v end		End of region
67
+ */
68
+void hide_region ( unsigned int region_id, physaddr_t start, physaddr_t end ) {
69
+	struct hidden_region *region = &hidden_regions[region_id];
70
+
71
+	/* Some operating systems get a nasty shock if a region of the
72
+	 * E820 map seems to start on a non-page boundary.  Make life
73
+	 * safer by rounding out our edited region.
74
+	 */	
75
+	region->start = ( start & ~( ALIGN_HIDDEN - 1 ) );
76
+	region->end = ( ( end + ALIGN_HIDDEN - 1 ) & ~( ALIGN_HIDDEN - 1 ) );
77
+	DBG ( "Hiding [%lx,%lx)\n", region->start, region->end );
78
+}
79
+
80
+/**
81
+ * Hide Etherboot text
82
+ *
83
+ */
84
+static void hide_text ( void ) {
85
+
86
+	/* The linker defines these symbols for us */
87
+	extern char _text[];
88
+	extern char _end[];
89
+
90
+	hide_region ( TEXT, virt_to_phys ( _text ), virt_to_phys ( _end ) );
91
+}
92
+
93
+/**
94
+ * Hide used base memory
95
+ *
96
+ */
97
+static void hide_basemem ( void ) {
98
+	uint16_t fbms;
99
+
100
+	/* Hide from the top of free base memory to 640kB.  Don't use
101
+	 * hide_region(), because we don't want this rounded to the
102
+	 * nearest page boundary.
103
+	 */
104
+	get_real ( fbms, BDA_SEG, BDA_FBMS );
105
+	hidden_regions[BASEMEM].start = ( fbms * 1024 );
106
+}
44
 
107
 
45
 /**
108
 /**
46
  * Hide Etherboot
109
  * Hide Etherboot
49
  * returned by the BIOS.
112
  * returned by the BIOS.
50
  */
113
  */
51
 void hide_etherboot ( void ) {
114
 void hide_etherboot ( void ) {
52
-	hidden_regions[TEXT].start = virt_to_phys ( _text );
53
-	hidden_regions[TEXT].end = virt_to_phys ( _end );
54
-	hidden_regions[BASEMEM].start = ( rm_cs << 4 );
55
 
115
 
56
-	DBG ( "Hiding [%lx,%lx) and [%lx,%lx)\n",
57
-	      ( unsigned long ) hidden_regions[TEXT].start,
58
-	      ( unsigned long ) hidden_regions[TEXT].end,
59
-	      ( unsigned long ) hidden_regions[BASEMEM].start,
60
-	      ( unsigned long ) hidden_regions[BASEMEM].end );
116
+	/* Initialise the hidden regions */
117
+	hide_text();
118
+	hide_basemem();
61
 
119
 
120
+	/* Hook INT 15 */
62
 	hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
121
 	hook_bios_interrupt ( 0x15, ( unsigned int ) int15,
63
 			      &int15_vector );
122
 			      &int15_vector );
64
 }
123
 }

+ 3
- 25
src/include/gpxe/hidemem.h View File

8
  *
8
  *
9
  */
9
  */
10
 
10
 
11
-/**
12
- * A hidden region of Etherboot
13
- *
14
- * This represents a region that will be edited out of the system's
15
- * memory map.
16
- *
17
- * This structure is accessed by assembly code, so must not be
18
- * changed.
19
- */
20
-struct hidden_region {
21
-	/* Physical start address */
22
-	physaddr_t start;
23
-	/* Physical end address */
24
-	physaddr_t end;
25
-};
26
-
27
 /**
11
 /**
28
  * Unique IDs for hidden regions
12
  * Unique IDs for hidden regions
29
  */
13
  */
30
-enum {
14
+enum hidemem_region_id {
31
 	TEXT = 0,
15
 	TEXT = 0,
32
 	BASEMEM,
16
 	BASEMEM,
33
 	EXTMEM,
17
 	EXTMEM,
34
 };
18
 };
35
 
19
 
36
-extern struct hidden_region __data16_array ( hidden_regions, [] );
37
-#define hidden_regions __use_data16 ( hidden_regions )
38
-
39
-static inline void hide_region ( unsigned int region,
40
-				 physaddr_t start, physaddr_t end ) {
41
-	hidden_regions[region].start = start;
42
-	hidden_regions[region].end = end;
43
-}
20
+extern void hide_region ( unsigned int region_id, physaddr_t start,
21
+			  physaddr_t end );
44
 
22
 
45
 #endif /* _GPXE_HIDEMEM_H */
23
 #endif /* _GPXE_HIDEMEM_H */

Loading…
Cancel
Save