hidemem.c File Reference

#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 Documentation

#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 )

Definition at line 53 of file hidemem.c.

Referenced by hide_basemem().

#define hidemem_umalloc   __use_data16 ( hidemem_umalloc )

Definition at line 57 of file hidemem.c.

Referenced by hide_umalloc().

#define hidemem_textdata   __use_data16 ( hidemem_textdata )

Definition at line 61 of file hidemem.c.

Referenced by hide_textdata().

#define int15_vector   __use_text16 ( int15_vector )

Definition at line 68 of file hidemem.c.

Referenced by hide_etherboot(), and unhide_etherboot().

#define _text16_memsz   ( ( unsigned int ) _text16_memsz )

Definition at line 74 of file hidemem.c.

Referenced by hide_etherboot().

#define _data16_memsz   ( ( unsigned int ) _data16_memsz )

Definition at line 76 of file hidemem.c.

Referenced by hide_etherboot().


Function Documentation

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 (  ) 

Assembly routine in e820mangler.S.

Referenced by hide_etherboot(), and unhide_etherboot().

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.

Parameters:
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.


Variable Documentation

char _textdata[]

char _etextdata[]

char _text16_memsz[]

char _data16_memsz[]


Generated on Tue Apr 6 20:01:12 2010 for gPXE by  doxygen 1.5.7.1