iPXE
Data Structures | Defines | Functions | Variables
int13con.c File Reference

INT13 disk log console. More...

#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <ipxe/console.h>
#include <ipxe/init.h>
#include <realmode.h>
#include <int13.h>
#include <config/console.h>

Go to the source code of this file.

Data Structures

struct  int13con_header
 Log partition header. More...

Defines

#define CONSOLE_INT13   ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#define INT13CON_DRIVE   0x80
 Disk drive number.
#define INT13CON_PARTITION_TYPE   0xe0
 Log partition type.
#define INT13CON_MAX_UNWRITTEN   64
 Maximum number of outstanding unwritten characters.
#define INT13CON_MAGIC   "iPXE LOG\n\n"
 Log partition magic signature.
#define int13con_vector   __use_data16 ( int13con_vector )
#define int13con_buffer   __use_data16 ( int13con_buffer )
#define int13con_address   __use_data16 ( int13con_address )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static struct segoff __bss16 (int13con_vector)
 Original INT13 vector.
static uint8_t __bss16_array (int13con_buffer,[INT13_BLKSIZE])
 Sector buffer.
static struct int13_disk_address __bss16 (int13con_address)
 Disk address packet.
static int int13con_rw (unsigned int op, uint64_t lba)
 Read/write disk sector.
static void int13con_putchar (int character)
 Write character to console.
static int int13con_find (void)
 Find log partition.
static void int13con_init (void)
 Initialise INT13 console.
struct init_fn int13con_init_fn __init_fn (INIT_CONSOLE)
 INT13 console initialisation function.

Variables

static uint64_t int13con_lba
 Current LBA.
static uint64_t int13con_max_lba
 Maximum LBA.
static size_t int13con_offset
 Current offset within sector.
static size_t int13con_unwritten
 Number of unwritten characters.
struct console_driver int13con __console_driver
 INT13 console driver.

Detailed Description

INT13 disk log console.

Definition in file int13con.c.


Define Documentation

Definition at line 44 of file int13con.c.

#define INT13CON_DRIVE   0x80

Disk drive number.

Definition at line 48 of file int13con.c.

Referenced by int13con_init(), and int13con_rw().

#define INT13CON_PARTITION_TYPE   0xe0

Log partition type.

Definition at line 51 of file int13con.c.

Referenced by int13con_find().

#define INT13CON_MAX_UNWRITTEN   64

Maximum number of outstanding unwritten characters.

Definition at line 54 of file int13con.c.

Referenced by int13con_putchar().

#define INT13CON_MAGIC   "iPXE LOG\n\n"

Log partition magic signature.

Definition at line 63 of file int13con.c.

Referenced by int13con_find().

Definition at line 67 of file int13con.c.

Referenced by int13con_init().

Definition at line 71 of file int13con.c.

Referenced by int13con_find(), int13con_putchar(), and int13con_rw().

Definition at line 75 of file int13con.c.

Referenced by int13con_rw().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static struct segoff __bss16 ( int13con_vector  ) [static, read]

Original INT13 vector.

static uint8_t __bss16_array ( int13con_buffer  ) [static]

Sector buffer.

static struct int13_disk_address __bss16 ( int13con_address  ) [static, read]

Disk address packet.

static int int13con_rw ( unsigned int  op,
uint64_t  lba 
) [static]

Read/write disk sector.

Parameters:
opOperation
lbaLogical block address
Return values:
rcReturn status code

Definition at line 98 of file int13con.c.

References __asm__(), __from_data16, DBG, EIO, error, int13con_address, int13con_buffer, INT13CON_DRIVE, lba, REAL_CODE, and rm_ds.

Referenced by int13con_find(), and int13con_putchar().

                                                         {
        uint8_t error;

        /* Construct disk address packet */
        int13con_address.bufsize = sizeof ( int13con_address );
        int13con_address.count = 1;
        int13con_address.buffer.segment = rm_ds;
        int13con_address.buffer.offset = __from_data16 ( int13con_buffer );
        int13con_address.lba = lba;

        /* 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 ) ) );
        if ( error ) {
                DBG ( "INT13CON operation %04x failed: %02x\n",
                      op, error );
                return -EIO;
        }

        return 0;
}
static void int13con_putchar ( int  character) [static]

Write character to console.

Parameters:
characterCharacter

Definition at line 132 of file int13con.c.

References DBG, INT13_BLKSIZE, INT13_EXTENDED_WRITE, int13con_buffer, INT13CON_MAX_UNWRITTEN, int13con_rw(), memset(), and rc.

                                               {
        static int busy;
        int rc;

        /* Ignore if we are already mid-logging */
        if ( busy )
                return;
        busy = 1;

        /* Write character to buffer */
        int13con_buffer[int13con_offset++] = character;
        int13con_unwritten++;

        /* Write sector to disk, if applicable */
        if ( ( int13con_offset == INT13_BLKSIZE ) ||
             ( int13con_unwritten == INT13CON_MAX_UNWRITTEN ) ||
             ( character == '\n' ) ) {

                /* Write sector to disk */
                if ( ( rc = int13con_rw ( INT13_EXTENDED_WRITE,
                                          int13con_lba ) ) != 0 ) {
                        DBG ( "INT13CON could not write log\n" );
                        /* Ignore and continue; there's nothing we can do */
                }

                /* Reset count of unwritten characters */
                int13con_unwritten = 0;
        }

        /* Move to next sector, if applicable */
        if ( int13con_offset == INT13_BLKSIZE ) {

                /* Disable console if we have run out of space */
                if ( int13con_lba >= int13con_max_lba )
                        int13con.disabled = 1;

                /* Clear log buffer */
                memset ( int13con_buffer, 0, sizeof ( int13con_buffer ) );
                int13con_offset = 0;

                /* Move to next sector */
                int13con_lba++;
        }

        /* Clear busy flag */
        busy = 0;
}
static int int13con_find ( void  ) [static]

Find log partition.

Return values:
rcReturn status code

Definition at line 185 of file int13con.c.

References DBG, DBG2_HDA, EINVAL, ENOENT, hdr, INT13_EXTENDED_READ, INT13_MBR_MAGIC, int13con_buffer, INT13CON_MAGIC, INT13CON_PARTITION_TYPE, int13con_rw(), length, partition_table_entry::length, int13con_header::magic, master_boot_record::magic, memcmp(), memcpy(), memset(), master_boot_record::partitions, rc, start, partition_table_entry::start, strerror(), and type.

Referenced by int13con_init().

                                  {
        struct master_boot_record *mbr =
                ( ( struct master_boot_record * ) int13con_buffer );
        struct int13con_header *hdr =
                ( ( struct int13con_header * ) int13con_buffer );
        struct partition_table_entry part[4];
        unsigned int i;
        int rc;

        /* Read MBR */
        if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, 0 ) ) != 0 ) {
                DBG ( "INT13CON could not read MBR: %s\n", strerror ( rc ) );
                return rc;
        }

        /* Check MBR magic */
        if ( mbr->magic != INT13_MBR_MAGIC ) {
                DBG ( "INT13CON incorrect MBR magic\n" );
                DBG2_HDA ( 0, mbr, sizeof ( *mbr ) );
                return -EINVAL;
        }

        /* Look for magic partition */
        memcpy ( part, mbr->partitions, sizeof ( part ) );
        for ( i = 0 ; i < ( sizeof ( part ) / sizeof ( part[0] ) ) ; i++ ) {

                /* Skip partitions of the wrong type */
                if ( part[i].type != INT13CON_PARTITION_TYPE )
                        continue;

                /* Read partition header */
                if ( ( rc = int13con_rw ( INT13_EXTENDED_READ,
                                          part[i].start ) ) != 0 ) {
                        DBG ( "INT13CON partition %d could not read header: "
                              "%s\n", ( i + 1 ), strerror ( rc ) );
                        continue;
                }

                /* Check partition header */
                if ( memcmp ( hdr->magic, INT13CON_MAGIC,
                              sizeof ( hdr->magic ) ) != 0 ) {
                        DBG ( "INT13CON partition %d bad magic\n", ( i + 1 ) );
                        DBG2_HDA ( 0, hdr, sizeof ( *hdr ) );
                        continue;
                }

                /* Found log partition */
                DBG ( "INT13CON partition %d at [%08x,%08x)\n", ( i + 1 ),
                      part[i].start, ( part[i].start + part[i].length ) );
                int13con_lba = part[i].start;
                int13con_max_lba = ( part[i].start + part[i].length - 1 );

                /* Initialise log buffer */
                memset ( &int13con_buffer[ sizeof ( *hdr ) ], 0,
                         ( sizeof ( int13con_buffer ) - sizeof ( *hdr ) ) );
                int13con_offset = sizeof ( hdr->magic );

                return 0;
        }

        DBG ( "INT13CON found no log partition\n" );
        return -ENOENT;
}
static void int13con_init ( void  ) [static]

Initialise INT13 console.

Definition at line 253 of file int13con.c.

References __asm__(), copy_from_real, DBG, error, INT13_EXTENSION_CHECK, INT13CON_DRIVE, int13con_find(), int13con_vector, rc, and REAL_CODE.

                                   {
        uint8_t error;
        uint16_t check;
        unsigned int discard_c;
        unsigned int discard_d;
        int rc;

        /* Check for INT13 extensions */
        __asm__ __volatile__ ( REAL_CODE ( "int $0x13\n\t"
                                           "setc %%al\n\t" )
                               : "=a" ( error ), "=b" ( check ),
                                 "=c" ( discard_c ), "=d" ( discard_d )
                               : "0" ( INT13_EXTENSION_CHECK << 8 ),
                                 "1" ( 0x55aa ), "3" ( INT13CON_DRIVE ) );
        if ( error || ( check != 0xaa55 ) ) {
                DBG ( "INT13CON missing extensions (%02x,%04x)\n",
                      error, check );
                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;

        /* Enable console */
        int13con.disabled = 0;
}
struct init_fn int13con_init_fn __init_fn ( INIT_CONSOLE  ) [read]

INT13 console initialisation function.


Variable Documentation

Current LBA.

Definition at line 78 of file int13con.c.

Maximum LBA.

Definition at line 81 of file int13con.c.

Current offset within sector.

Definition at line 84 of file int13con.c.

Number of unwritten characters.

Definition at line 87 of file int13con.c.

Initial value:
 {
        .putchar = int13con_putchar,
        .disabled = CONSOLE_DISABLED,
        .usage = CONSOLE_INT13,
}

INT13 console driver.

Definition at line 89 of file int13con.c.