iPXE
Macros | Functions
biosint.h File Reference
#include <realmode.h>

Go to the source code of this file.

Macros

#define hooked_bios_interrupts   __use_text16 ( hooked_bios_interrupts )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
uint16_t __text16 (hooked_bios_interrupts)
 Hooked interrupt count. More...
 
void hook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Hook INT vector. More...
 
int unhook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Unhook INT vector. More...
 
void check_bios_interrupts (void)
 Dump changes to interrupt vector table (for debugging) More...
 

Macro Definition Documentation

◆ hooked_bios_interrupts

#define hooked_bios_interrupts   __use_text16 ( hooked_bios_interrupts )

Definition at line 25 of file biosint.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __text16()

Hooked interrupt count.

At exit, after unhooking all possible interrupts, this counter should be examined. If it is non-zero, it means that we failed to unhook at least one interrupt vector, and so must not free up the memory we are using. (Note that this also implies that we should re-hook INT 15 in order to hide ourselves from the memory map).

◆ hook_bios_interrupt()

void hook_bios_interrupt ( unsigned int  interrupt,
unsigned int  handler,
struct segoff chain_vector 
)

Hook INT vector.

Parameters
interruptINT number
handlerOffset within .text16 to interrupt handler
chain_vectorVector for chaining to previous handler

Hooks in an i386 INT handler. The handler itself must reside within the .text16 segment. chain_vector will be filled in with the address of the previously-installed handler for this interrupt; the handler should probably exit by ljmping via this vector.

Definition at line 24 of file biosint.c.

25  {
26  struct segoff vector = {
27  .segment = rm_cs,
28  .offset = handler,
29  };
30 
31  DBG ( "Hooking INT %#02x to %04x:%04x\n",
32  interrupt, rm_cs, handler );
33 
34  if ( ( chain_vector->segment != 0 ) ||
35  ( chain_vector->offset != 0 ) ) {
36  /* Already hooked; do nothing */
37  DBG ( "...already hooked\n" );
38  return;
39  }
40 
41  copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
42  sizeof ( *chain_vector ) );
43  DBG ( "...chaining to %04x:%04x\n",
44  chain_vector->segment, chain_vector->offset );
45  if ( DBG_LOG ) {
46  char code[64];
47  copy_from_real ( code, chain_vector->segment,
48  chain_vector->offset, sizeof ( code ) );
49  DBG_HDA ( *chain_vector, code, sizeof ( code ) );
50  }
51 
52  copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
54 }
uint16_t segment
Definition: registers.h:193
#define DBG_HDA(...)
Definition: compiler.h:499
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint16_t offset
Definition: registers.h:192
#define hooked_bios_interrupts
Definition: biosint.h:25
#define copy_to_real
Definition: libkir.h:78
#define copy_from_real
Definition: libkir.h:79
uint8_t code
Response code.
Definition: scsi.h:16
#define rm_cs
Definition: libkir.h:38
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define DBG_LOG
Definition: compiler.h:317
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
Definition: librm_mgmt.c:250

References code, copy_from_real, copy_to_real, DBG, DBG_HDA, DBG_LOG, hooked_bios_interrupts, interrupt(), segoff::offset, rm_cs, segoff::segment, and vector.

Referenced by bios_inject_startup(), call_bootsector(), fake_e820(), hide_etherboot(), hook_comboot_interrupts(), int13_hook_vector(), pxe_activate(), rtc_hook_isr(), and undinet_hook_isr().

◆ unhook_bios_interrupt()

int unhook_bios_interrupt ( unsigned int  interrupt,
unsigned int  handler,
struct segoff chain_vector 
)

Unhook INT vector.

Parameters
interruptINT number
handlerOffset within .text16 to interrupt handler
chain_vectorVector containing address of previous handler

Unhooks an i386 interrupt handler hooked by hook_i386_vector(). Note that this operation may fail, if some external code has hooked the vector since we hooked in our handler. If it fails, it means that it is not possible to unhook our handler, and we must leave it (and its chaining vector) resident in memory.

Definition at line 69 of file biosint.c.

70  {
71  struct segoff vector;
72 
73  DBG ( "Unhooking INT %#02x from %04x:%04x\n",
74  interrupt, rm_cs, handler );
75 
76  copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) );
77  if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) ) {
78  DBG ( "...cannot unhook; vector points to %04x:%04x\n",
79  vector.segment, vector.offset );
80  return -EBUSY;
81  }
82 
83  DBG ( "...restoring to %04x:%04x\n",
84  chain_vector->segment, chain_vector->offset );
85  copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
86  sizeof ( *chain_vector ) );
87 
88  chain_vector->segment = 0;
89  chain_vector->offset = 0;
91  return 0;
92 }
uint16_t segment
Definition: registers.h:193
#define EBUSY
Device or resource busy.
Definition: errno.h:338
uint32_t vector
MSI-X vector.
Definition: ena.h:20
uint16_t offset
Definition: registers.h:192
#define hooked_bios_interrupts
Definition: biosint.h:25
#define copy_to_real
Definition: libkir.h:78
#define copy_from_real
Definition: libkir.h:79
#define rm_cs
Definition: libkir.h:38
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
Definition: librm_mgmt.c:250

References copy_from_real, copy_to_real, DBG, EBUSY, hooked_bios_interrupts, interrupt(), segoff::offset, rm_cs, segoff::segment, and vector.

Referenced by bios_inject_shutdown(), call_bootsector(), int13_unhook_vector(), pxe_deactivate(), rtc_unhook_isr(), undinet_unhook_isr(), unfake_e820(), unhide_etherboot(), and unhook_comboot_interrupts().

◆ check_bios_interrupts()

void check_bios_interrupts ( void  )

Dump changes to interrupt vector table (for debugging)

Definition at line 98 of file biosint.c.

98  {
99  static struct segoff vectors[256];
100  static uint8_t initialised;
101  struct segoff vector;
102  unsigned int i;
103 
104  /* Print any changed interrupt vectors */
105  for ( i = 0; i < ( sizeof ( vectors ) / sizeof ( vectors[0] ) ); i++ ) {
106  copy_from_real ( &vector, 0, ( i * sizeof ( vector ) ),
107  sizeof ( vector ) );
108  if ( memcmp ( &vector, &vectors[i], sizeof ( vector ) ) == 0 )
109  continue;
110  if ( initialised ) {
111  dbg_printf ( "INT %02x changed %04x:%04x => "
112  "%04x:%04x\n", i, vectors[i].segment,
113  vectors[i].offset, vector.segment,
114  vector.offset );
115  }
116  memcpy ( &vectors[i], &vector, sizeof ( vectors[i] ) );
117  }
118  initialised = 1;
119 }
uint16_t segment
Code segment.
Definition: librm.h:252
uint32_t vector
MSI-X vector.
Definition: ena.h:20
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
unsigned char uint8_t
Definition: stdint.h:10
#define copy_from_real
Definition: libkir.h:79
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
void dbg_printf(const char *fmt,...)
Print debug message.
Definition: debug.c:38

References copy_from_real, dbg_printf(), memcmp(), memcpy(), offset, segment, and vector.