#include <assert.h>#include <realmode.h>#include <biosint.h>#include <basemem.h>#include <fakee820.h>#include <gpxe/init.h>#include <gpxe/memmap.h>#include <gpxe/hidemem.h>Go to the source code of this file.
Data Structures | |
| struct | hidden_region |
| A hidden region of gPXE. More... | |
Defines | |
| #define | FAKE_E820 0 |
| Set to true if you want to test a fake E820 map. | |
| #define | ALIGN_HIDDEN 4096 |
| Alignment for hidden memory regions. | |
| #define | hidemem_base __use_data16 ( hidemem_base ) |
| #define | hidemem_umalloc __use_data16 ( hidemem_umalloc ) |
| #define | hidemem_textdata __use_data16 ( hidemem_textdata ) |
| #define | int15_vector __use_text16 ( int15_vector ) |
| #define | _text16_memsz ( ( unsigned int ) _text16_memsz ) |
| #define | _data16_memsz ( ( unsigned int ) _data16_memsz ) |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| struct hidden_region | __data16 (hidemem_base) |
| Hidden base memory. | |
| struct hidden_region | __data16 (hidemem_umalloc) |
| Hidden umalloc memory. | |
| struct hidden_region | __data16 (hidemem_textdata) |
| Hidden text memory. | |
| void | int15 () |
| Assembly routine in e820mangler.S. | |
| struct segoff | __text16 (int15_vector) |
| Vector for storing original INT 15 handler. | |
| static void | hide_region (struct hidden_region *region, physaddr_t start, physaddr_t end) |
| Hide region of memory from system memory map. | |
| void | hide_basemem (void) |
| Hide used base memory. | |
| void | hide_umalloc (physaddr_t start, physaddr_t end) |
| Hide umalloc() region. | |
| void | hide_textdata (void) |
| Hide .text and .data. | |
| static void | hide_etherboot (void) |
| Hide Etherboot. | |
| static void | unhide_etherboot (int flags __unused) |
| Unhide Etherboot. | |
| struct startup_fn hide_etherboot_startup_fn | __startup_fn (STARTUP_EARLY) |
| Hide Etherboot startup function. | |
Variables | |
| char | _textdata [] |
| char | _etextdata [] |
| char | _text16_memsz [] |
| char | _data16_memsz [] |
| #define FAKE_E820 0 |
Set to true if you want to test a fake E820 map.
Definition at line 30 of file hidemem.c.
Referenced by hide_etherboot(), and unhide_etherboot().
| #define ALIGN_HIDDEN 4096 |
Alignment for hidden memory regions.
Definition at line 33 of file hidemem.c.
Referenced by hide_region().
| #define hidemem_base __use_data16 ( hidemem_base ) |
| #define hidemem_umalloc __use_data16 ( hidemem_umalloc ) |
| #define hidemem_textdata __use_data16 ( hidemem_textdata ) |
| #define int15_vector __use_text16 ( int15_vector ) |
| #define _text16_memsz ( ( unsigned int ) _text16_memsz ) |
| #define _data16_memsz ( ( unsigned int ) _data16_memsz ) |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| struct hidden_region __data16 | ( | hidemem_base | ) | [read] |
Hidden base memory.
| struct hidden_region __data16 | ( | hidemem_umalloc | ) | [read] |
Hidden umalloc memory.
| struct hidden_region __data16 | ( | hidemem_textdata | ) | [read] |
Hidden text memory.
| void int15 | ( | ) |
| struct segoff __text16 | ( | int15_vector | ) | [read] |
Vector for storing original INT 15 handler.
| static void hide_region | ( | struct hidden_region * | region, | |
| physaddr_t | start, | |||
| physaddr_t | end | |||
| ) | [static] |
Hide region of memory from system memory map.
| region | Hidden memory region | |
| start | Start of region | |
| end | End of region |
Definition at line 85 of file hidemem.c.
References ALIGN_HIDDEN, DBG, hidden_region::end, and hidden_region::start.
Referenced by hide_textdata(), and hide_umalloc().
00086 { 00087 00088 /* Some operating systems get a nasty shock if a region of the 00089 * E820 map seems to start on a non-page boundary. Make life 00090 * safer by rounding out our edited region. 00091 */ 00092 region->start = ( start & ~( ALIGN_HIDDEN - 1 ) ); 00093 region->end = ( ( end + ALIGN_HIDDEN - 1 ) & ~( ALIGN_HIDDEN - 1 ) ); 00094 00095 DBG ( "Hiding region [%llx,%llx)\n", region->start, region->end ); 00096 }
| void hide_basemem | ( | void | ) |
Hide used base memory.
Definition at line 102 of file hidemem.c.
References get_fbms(), and hidemem_base.
Referenced by hide_etherboot(), and set_fbms().
00102 { 00103 /* Hide from the top of free base memory to 640kB. Don't use 00104 * hide_region(), because we don't want this rounded to the 00105 * nearest page boundary. 00106 */ 00107 hidemem_base.start = ( get_fbms() * 1024 ); 00108 }
| void hide_umalloc | ( | physaddr_t | start, | |
| physaddr_t | end | |||
| ) |
Hide umalloc() region.
Definition at line 114 of file hidemem.c.
References _textdata, assert, hide_region(), hidemem_umalloc, and virt_to_phys().
Referenced by hide_etherboot(), and memtop_urealloc().
00114 { 00115 assert ( end <= virt_to_phys ( _textdata ) ); 00116 hide_region ( &hidemem_umalloc, start, end ); 00117 }
| void hide_textdata | ( | void | ) |
Hide .text and .data.
Definition at line 123 of file hidemem.c.
References _etextdata, _textdata, hide_region(), hidemem_textdata, and virt_to_phys().
Referenced by hide_etherboot().
00123 { 00124 hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), 00125 virt_to_phys ( _etextdata ) ); 00126 }
| static void hide_etherboot | ( | void | ) | [static] |
Hide Etherboot.
Installs an INT 15 handler to edit Etherboot out of the memory map returned by the BIOS.
Definition at line 134 of file hidemem.c.
References _data16_memsz, _text16_memsz, _textdata, DBG, fake_e820(), FAKE_E820, get_fbms(), get_memmap(), hide_basemem(), hide_textdata(), hide_umalloc(), hook_bios_interrupt(), int15(), int15_vector, rm_cs, rm_ds, and virt_to_phys().
00134 { 00135 struct memory_map memmap; 00136 unsigned int rm_ds_top; 00137 unsigned int rm_cs_top; 00138 unsigned int fbms; 00139 00140 /* Dump memory map before mangling */ 00141 DBG ( "Hiding gPXE from system memory map\n" ); 00142 get_memmap ( &memmap ); 00143 00144 /* Hook in fake E820 map, if we're testing one */ 00145 if ( FAKE_E820 ) { 00146 DBG ( "Hooking in fake E820 map\n" ); 00147 fake_e820(); 00148 get_memmap ( &memmap ); 00149 } 00150 00151 /* Initialise the hidden regions */ 00152 hide_basemem(); 00153 hide_umalloc ( virt_to_phys ( _textdata ), virt_to_phys ( _textdata ) ); 00154 hide_textdata(); 00155 00156 /* Some really moronic BIOSes bring up the PXE stack via the 00157 * UNDI loader entry point and then don't bother to unload it 00158 * before overwriting the code and data segments. If this 00159 * happens, we really don't want to leave INT 15 hooked, 00160 * because that will cause any loaded OS to die horribly as 00161 * soon as it attempts to fetch the system memory map. 00162 * 00163 * We use a heuristic to guess whether or not we are being 00164 * loaded sensibly. 00165 */ 00166 rm_cs_top = ( ( ( rm_cs << 4 ) + _text16_memsz + 1024 - 1 ) >> 10 ); 00167 rm_ds_top = ( ( ( rm_ds << 4 ) + _data16_memsz + 1024 - 1 ) >> 10 ); 00168 fbms = get_fbms(); 00169 if ( ( rm_cs_top < fbms ) && ( rm_ds_top < fbms ) ) { 00170 DBG ( "Detected potentially unsafe UNDI load at CS=%04x " 00171 "DS=%04x FBMS=%dkB\n", rm_cs, rm_ds, fbms ); 00172 DBG ( "Disabling INT 15 memory hiding\n" ); 00173 return; 00174 } 00175 00176 /* Hook INT 15 */ 00177 hook_bios_interrupt ( 0x15, ( unsigned int ) int15, 00178 &int15_vector ); 00179 00180 /* Dump memory map after mangling */ 00181 DBG ( "Hidden gPXE from system memory map\n" ); 00182 get_memmap ( &memmap ); 00183 }
| static void unhide_etherboot | ( | int flags | __unused | ) | [static] |
Unhide Etherboot.
Uninstalls the INT 15 handler installed by hide_etherboot(), if possible.
Definition at line 191 of file hidemem.c.
References DBG, FAKE_E820, hooked_bios_interrupts, int15(), int15_vector, unfake_e820(), and unhook_bios_interrupt().
00191 { 00192 00193 /* If we have more than one hooked interrupt at this point, it 00194 * means that some other vector is still hooked, in which case 00195 * we can't safely unhook INT 15 because we need to keep our 00196 * memory protected. (We expect there to be at least one 00197 * hooked interrupt, because INT 15 itself is still hooked). 00198 */ 00199 if ( hooked_bios_interrupts > 1 ) { 00200 DBG ( "Cannot unhide: %d interrupt vectors still hooked\n", 00201 hooked_bios_interrupts ); 00202 return; 00203 } 00204 00205 /* Try to unhook INT 15. If it fails, then just leave it 00206 * hooked; it takes care of protecting itself. :) 00207 */ 00208 unhook_bios_interrupt ( 0x15, ( unsigned int ) int15, 00209 &int15_vector ); 00210 00211 /* Unhook fake E820 map, if used */ 00212 if ( FAKE_E820 ) 00213 unfake_e820(); 00214 }
| struct startup_fn hide_etherboot_startup_fn __startup_fn | ( | STARTUP_EARLY | ) | [read] |
Hide Etherboot startup function.
| char _textdata[] |
| char _etextdata[] |
| char _text16_memsz[] |
| char _data16_memsz[] |
1.5.7.1