summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2017-03-27 09:50:59 +0200
committerMichael Brown2017-03-27 09:50:59 +0200
commitc73af29fe206dda55a72119b6b29c5628aa09ed1 (patch)
tree38a0dcad6a8ac013e82e48943c73239bf9a479cc /src/arch
parent[int13] Improve geometry guessing for unaligned partitions (diff)
downloadipxe-c73af29fe206dda55a72119b6b29c5628aa09ed1.tar.gz
ipxe-c73af29fe206dda55a72119b6b29c5628aa09ed1.tar.xz
ipxe-c73af29fe206dda55a72119b6b29c5628aa09ed1.zip
[int13con] Avoid overwriting random portions of SAN boot disks
The INT13 console type (CONSOLE_INT13) autodetects at initialisation time a magic partition to be used for logging iPXE console output. If the INT13 drive number mapping is subsequently changed (e.g. because iPXE was used to perform a SAN boot), then the console logging output will be written to the incorrect disk. Fix by recording the INT13 vector at initialisation time, and using this original vector to emulate INT13 calls for all subsequent accesses. This should be robust against drive remapping performed either by ourselves or by another bootloader (e.g. a chainloaded undionly.kpxe which then performs a SAN boot). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/interface/pcbios/int13con.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/arch/x86/interface/pcbios/int13con.c b/src/arch/x86/interface/pcbios/int13con.c
index 2414c690..8106cd15 100644
--- a/src/arch/x86/interface/pcbios/int13con.c
+++ b/src/arch/x86/interface/pcbios/int13con.c
@@ -62,6 +62,10 @@ struct int13con_header {
/** Log partition magic signature */
#define INT13CON_MAGIC "iPXE LOG\n\n"
+/** Original INT13 vector */
+static struct segoff __bss16 ( int13con_vector );
+#define int13con_vector __use_data16 ( int13con_vector )
+
/** Sector buffer */
static uint8_t __bss16_array ( int13con_buffer, [INT13_BLKSIZE] );
#define int13con_buffer __use_data16 ( int13con_buffer )
@@ -101,8 +105,13 @@ static int int13con_rw ( unsigned int op, uint64_t lba ) {
int13con_address.buffer.offset = __from_data16 ( int13con_buffer );
int13con_address.lba = lba;
- /* Issue INT13 */
- __asm__ ( REAL_CODE ( "int $0x13\n\t" )
+ /* Emulate INT13 via original vector. We do this since iPXE
+ * (or another subsequent bootloader) may hook INT13 and remap
+ * drive numbers.
+ */
+ __asm__ ( REAL_CODE ( "pushfw\n\t"
+ "cli\n\t"
+ "lcall *int13con_vector\n\t" )
: "=a" ( error )
: "0" ( op << 8 ), "d" ( INT13CON_DRIVE ),
"S" ( __from_data16 ( &int13con_address ) ) );
@@ -261,6 +270,12 @@ static void int13con_init ( void ) {
return;
}
+ /* Store original INT13 vector */
+ copy_from_real ( &int13con_vector, 0, ( 0x13 * 4 ),
+ sizeof ( int13con_vector ) );
+ DBG ( "INT13CON using original INT13 vector %04x:%04x\n",
+ int13con_vector.segment, int13con_vector.offset );
+
/* Locate log partition */
if ( ( rc = int13con_find() ) != 0)
return;