iPXE
Functions
biosint.c File Reference
#include <string.h>
#include <errno.h>
#include <realmode.h>
#include <biosint.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
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...
 

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ 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 25 of file biosint.c.

26  {
27  struct segoff vector = {
28  .segment = rm_cs,
29  .offset = handler,
30  };
31 
32  DBG ( "Hooking INT %#02x to %04x:%04x\n",
33  interrupt, rm_cs, handler );
34 
35  if ( ( chain_vector->segment != 0 ) ||
36  ( chain_vector->offset != 0 ) ) {
37  /* Already hooked; do nothing */
38  DBG ( "...already hooked\n" );
39  return;
40  }
41 
42  copy_from_real ( chain_vector, 0, ( interrupt * 4 ),
43  sizeof ( *chain_vector ) );
44  DBG ( "...chaining to %04x:%04x\n",
45  chain_vector->segment, chain_vector->offset );
46  if ( DBG_LOG ) {
47  char code[64];
48  copy_from_real ( code, chain_vector->segment,
49  chain_vector->offset, sizeof ( code ) );
50  DBG_HDA ( *chain_vector, code, sizeof ( code ) );
51  }
52 
53  copy_to_real ( 0, ( interrupt * 4 ), &vector, sizeof ( vector ) );
55 }
uint16_t segment
Definition: registers.h:193
#define DBG_HDA(...)
Definition: compiler.h:499
uint32_t vector
MSI-X vector.
Definition: ena.h:20
static unsigned int code
Response code.
Definition: hyperv.h:26
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
#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:251

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 70 of file biosint.c.

71  {
72  struct segoff vector;
73 
74  DBG ( "Unhooking INT %#02x from %04x:%04x\n",
75  interrupt, rm_cs, handler );
76 
77  copy_from_real ( &vector, 0, ( interrupt * 4 ), sizeof ( vector ) );
78  if ( ( vector.segment != rm_cs ) || ( vector.offset != handler ) ) {
79  DBG ( "...cannot unhook; vector points to %04x:%04x\n",
80  vector.segment, vector.offset );
81  return -EBUSY;
82  }
83 
84  DBG ( "...restoring to %04x:%04x\n",
85  chain_vector->segment, chain_vector->offset );
86  copy_to_real ( 0, ( interrupt * 4 ), chain_vector,
87  sizeof ( *chain_vector ) );
88 
89  chain_vector->segment = 0;
90  chain_vector->offset = 0;
92  return 0;
93 }
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:251

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 99 of file biosint.c.

99  {
100  static struct segoff vectors[256];
101  static uint8_t initialised;
102  struct segoff vector;
103  unsigned int i;
104 
105  /* Print any changed interrupt vectors */
106  for ( i = 0; i < ( sizeof ( vectors ) / sizeof ( vectors[0] ) ); i++ ) {
107  copy_from_real ( &vector, 0, ( i * sizeof ( vector ) ),
108  sizeof ( vector ) );
109  if ( memcmp ( &vector, &vectors[i], sizeof ( vector ) ) == 0 )
110  continue;
111  if ( initialised ) {
112  dbg_printf ( "INT %02x changed %04x:%04x => "
113  "%04x:%04x\n", i, vectors[i].segment,
114  vectors[i].offset, vector.segment,
115  vector.offset );
116  }
117  memcpy ( &vectors[i], &vector, sizeof ( vectors[i] ) );
118  }
119  initialised = 1;
120 }
uint16_t segment
Code segment.
Definition: librm.h:138
uint32_t vector
MSI-X vector.
Definition: ena.h:20
void * memcpy(void *dest, const void *src, size_t len) __nonnull
unsigned char uint8_t
Definition: stdint.h:10
#define copy_from_real
Definition: libkir.h:79
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
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.