iPXE
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.
void hook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Hook INT vector.
int unhook_bios_interrupt (unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
 Unhook INT vector.
void check_bios_interrupts (void)
 Dump changes to interrupt vector table (for debugging)

Macro Definition Documentation

◆ hooked_bios_interrupts

#define hooked_bios_interrupts   __use_text16 ( hooked_bios_interrupts )

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ __text16()

uint16_t __text16 ( hooked_bios_interrupts )
extern

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

References hooked_bios_interrupts.

◆ hook_bios_interrupt()

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

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}
static unsigned int code
Response code.
Definition hyperv.h:26
#define hooked_bios_interrupts
Definition biosint.h:25
uint32_t vector
MSI-X vector.
Definition ena.h:9
#define DBG_HDA(...)
Definition compiler.h:499
#define DBG_LOG
Definition compiler.h:317
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define rm_cs
Definition libkir.h:38
#define copy_to_real
Definition libkir.h:78
#define copy_from_real
Definition libkir.h:79
void interrupt(int intr, struct interrupt_frame32 *frame32, struct interrupt_frame64 *frame64)
Interrupt handler.
Definition librm_mgmt.c:251
uint16_t segment
Definition registers.h:193
uint16_t offset
Definition registers.h:192

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

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}
#define EBUSY
Device or resource busy.
Definition errno.h:339

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

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}
unsigned char uint8_t
Definition stdint.h:10
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void dbg_printf(const char *fmt,...)
Print debug message.
Definition debug.c:39
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint16_t segment
Code segment.
Definition librm.h:3
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

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