iPXE
int13.h
Go to the documentation of this file.
00001 #ifndef INT13_H
00002 #define INT13_H
00003 
00004 /** @file
00005  *
00006  * INT 13 emulation
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/list.h>
00014 #include <ipxe/edd.h>
00015 #include <realmode.h>
00016 
00017 /**
00018  * @defgroup int13ops INT 13 operation codes
00019  * @{
00020  */
00021 
00022 /** Reset disk system */
00023 #define INT13_RESET                     0x00
00024 /** Get status of last operation */
00025 #define INT13_GET_LAST_STATUS           0x01
00026 /** Read sectors */
00027 #define INT13_READ_SECTORS              0x02
00028 /** Write sectors */
00029 #define INT13_WRITE_SECTORS             0x03
00030 /** Get drive parameters */
00031 #define INT13_GET_PARAMETERS            0x08
00032 /** Get disk type */
00033 #define INT13_GET_DISK_TYPE             0x15
00034 /** Extensions installation check */
00035 #define INT13_EXTENSION_CHECK           0x41
00036 /** Extended read */
00037 #define INT13_EXTENDED_READ             0x42
00038 /** Extended write */
00039 #define INT13_EXTENDED_WRITE            0x43
00040 /** Verify sectors */
00041 #define INT13_EXTENDED_VERIFY           0x44
00042 /** Extended seek */
00043 #define INT13_EXTENDED_SEEK             0x47
00044 /** Get extended drive parameters */
00045 #define INT13_GET_EXTENDED_PARAMETERS   0x48
00046 /** Get CD-ROM status / terminate emulation */
00047 #define INT13_CDROM_STATUS_TERMINATE    0x4b
00048 /** Read CD-ROM boot catalog */
00049 #define INT13_CDROM_READ_BOOT_CATALOG   0x4d
00050 
00051 /** @} */
00052 
00053 /**
00054  * @defgroup int13status INT 13 status codes
00055  * @{
00056  */
00057 
00058 /** Operation completed successfully */
00059 #define INT13_STATUS_SUCCESS            0x00
00060 /** Invalid function or parameter */
00061 #define INT13_STATUS_INVALID            0x01
00062 /** Read error */
00063 #define INT13_STATUS_READ_ERROR         0x04
00064 /** Reset failed */
00065 #define INT13_STATUS_RESET_FAILED       0x05
00066 /** Write error */
00067 #define INT13_STATUS_WRITE_ERROR        0xcc
00068 
00069 /** @} */
00070 
00071 /** Block size for non-extended INT 13 calls */
00072 #define INT13_BLKSIZE 512
00073 
00074 /** @defgroup int13fddtype INT 13 floppy disk drive types
00075  * @{
00076  */
00077 
00078 /** 360K */
00079 #define INT13_FDD_TYPE_360K             0x01
00080 /** 1.2M */
00081 #define INT13_FDD_TYPE_1M2              0x02
00082 /** 720K */
00083 #define INT13_FDD_TYPE_720K             0x03
00084 /** 1.44M */
00085 #define INT13_FDD_TYPE_1M44             0x04
00086 
00087 /** An INT 13 disk address packet */
00088 struct int13_disk_address {
00089         /** Size of the packet, in bytes */
00090         uint8_t bufsize;
00091         /** Reserved */
00092         uint8_t reserved_a;
00093         /** Block count */
00094         uint8_t count;
00095         /** Reserved */
00096         uint8_t reserved_b;
00097         /** Data buffer */
00098         struct segoff buffer;
00099         /** Starting block number */
00100         uint64_t lba;
00101         /** Data buffer (EDD 3.0+ only) */
00102         uint64_t buffer_phys;
00103         /** Block count (EDD 4.0+ only) */
00104         uint32_t long_count;
00105         /** Reserved */
00106         uint32_t reserved_c;
00107 } __attribute__ (( packed ));
00108 
00109 /** INT 13 disk parameters */
00110 struct int13_disk_parameters {
00111         /** Size of this structure */
00112         uint16_t bufsize;
00113         /** Flags */
00114         uint16_t flags;
00115         /** Number of cylinders */
00116         uint32_t cylinders;
00117         /** Number of heads */
00118         uint32_t heads;
00119         /** Number of sectors per track */
00120         uint32_t sectors_per_track;
00121         /** Total number of sectors on drive */
00122         uint64_t sectors;
00123         /** Bytes per sector */
00124         uint16_t sector_size;
00125         /** Device parameter table extension */
00126         struct segoff dpte;
00127         /** Device path information */
00128         struct edd_device_path_information dpi;
00129 } __attribute__ (( packed ));
00130 
00131 /**
00132  * @defgroup int13types INT 13 disk types
00133  * @{
00134  */
00135 
00136 /** No such drive */
00137 #define INT13_DISK_TYPE_NONE    0x00
00138 /** Floppy without change-line support */
00139 #define INT13_DISK_TYPE_FDD     0x01
00140 /** Floppy with change-line support */
00141 #define INT13_DISK_TYPE_FDD_CL  0x02
00142 /** Hard disk */
00143 #define INT13_DISK_TYPE_HDD     0x03
00144 
00145 /** @} */
00146 
00147 /**
00148  * @defgroup int13flags INT 13 disk parameter flags
00149  * @{
00150  */
00151 
00152 /** DMA boundary errors handled transparently */
00153 #define INT13_FL_DMA_TRANSPARENT 0x01
00154 /** CHS information is valid */
00155 #define INT13_FL_CHS_VALID       0x02
00156 /** Removable drive */
00157 #define INT13_FL_REMOVABLE       0x04
00158 /** Write with verify supported */
00159 #define INT13_FL_VERIFIABLE      0x08
00160 /** Has change-line supported (valid only for removable drives) */
00161 #define INT13_FL_CHANGE_LINE     0x10
00162 /** Drive can be locked (valid only for removable drives) */
00163 #define INT13_FL_LOCKABLE        0x20
00164 /** CHS is max possible, not current media (valid only for removable drives) */
00165 #define INT13_FL_CHS_MAX         0x40
00166 
00167 /** @} */
00168 
00169 /**
00170  * @defgroup int13exts INT 13 extension flags
00171  * @{
00172  */
00173 
00174 /** Extended disk access functions supported */
00175 #define INT13_EXTENSION_LINEAR          0x01
00176 /** Removable drive functions supported */
00177 #define INT13_EXTENSION_REMOVABLE       0x02
00178 /** EDD functions supported */
00179 #define INT13_EXTENSION_EDD             0x04
00180 /** 64-bit extensions are present */
00181 #define INT13_EXTENSION_64BIT           0x08
00182 
00183 /** @} */
00184 
00185 /**
00186  * @defgroup int13vers INT 13 extension versions
00187  * @{
00188  */
00189 
00190 /** INT13 extensions version 1.x */
00191 #define INT13_EXTENSION_VER_1_X         0x01
00192 /** INT13 extensions version 2.0 (EDD-1.0) */
00193 #define INT13_EXTENSION_VER_2_0         0x20
00194 /** INT13 extensions version 2.1 (EDD-1.1) */
00195 #define INT13_EXTENSION_VER_2_1         0x21
00196 /** INT13 extensions version 3.0 (EDD-3.0) */
00197 #define INT13_EXTENSION_VER_3_0         0x30
00198 
00199 /** @} */ 
00200 
00201 /** Maximum number of sectors for which CHS geometry is allowed to be valid
00202  *
00203  * This number is taken from the EDD specification.
00204  */
00205 #define INT13_MAX_CHS_SECTORS           15482880
00206 
00207 /** Bootable CD-ROM specification packet */
00208 struct int13_cdrom_specification {
00209         /** Size of packet in bytes */
00210         uint8_t size;
00211         /** Boot media type */
00212         uint8_t media_type;
00213         /** Drive number */
00214         uint8_t drive;
00215         /** CD-ROM controller number */
00216         uint8_t controller;
00217         /** LBA of disk image to emulate */
00218         uint32_t lba;
00219         /** Device specification */
00220         uint16_t device;
00221         /** Segment of 3K buffer for caching CD-ROM reads */
00222         uint16_t cache_segment;
00223         /** Load segment for initial boot image */
00224         uint16_t load_segment;
00225         /** Number of 512-byte sectors to load */
00226         uint16_t load_sectors;
00227         /** Low 8 bits of cylinder number */
00228         uint8_t cyl;
00229         /** Sector number, plus high 2 bits of cylinder number */
00230         uint8_t cyl_sector;
00231         /** Head number */
00232         uint8_t head;
00233 } __attribute__ (( packed ));
00234 
00235 /** Bootable CD-ROM boot catalog command packet */
00236 struct int13_cdrom_boot_catalog_command {
00237         /** Size of packet in bytes */
00238         uint8_t size;
00239         /** Number of sectors of boot catalog to read */
00240         uint8_t count;
00241         /** Buffer for boot catalog */
00242         uint32_t buffer;
00243         /** First sector in boot catalog to transfer */
00244         uint16_t start;
00245 } __attribute__ (( packed ));
00246 
00247 /** A C/H/S address within a partition table entry */
00248 struct partition_chs {
00249         /** Head number */
00250         uint8_t head;
00251         /** Sector number, plus high 2 bits of cylinder number */
00252         uint8_t cyl_sector;
00253         /** Low 8 bits of cylinder number */
00254         uint8_t cyl;
00255 } __attribute__ (( packed ));
00256 
00257 #define PART_HEAD(chs) ( (chs).head )
00258 #define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f )
00259 #define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) )
00260 
00261 /** A partition table entry within the MBR */
00262 struct partition_table_entry {
00263         /** Bootable flag */
00264         uint8_t bootable;
00265         /** C/H/S start address */
00266         struct partition_chs chs_start;
00267         /** System indicator (partition type) */
00268         uint8_t type;
00269         /** C/H/S end address */
00270         struct partition_chs chs_end;
00271         /** Linear start address */
00272         uint32_t start;
00273         /** Linear length */
00274         uint32_t length;
00275 } __attribute__ (( packed ));
00276 
00277 /** A Master Boot Record */
00278 struct master_boot_record {
00279         /** Code area */
00280         uint8_t code[440];
00281         /** Disk signature */
00282         uint32_t signature;
00283         /** Padding */
00284         uint8_t pad[2];
00285         /** Partition table */
00286         struct partition_table_entry partitions[4];
00287         /** 0x55aa MBR signature */
00288         uint16_t magic;
00289 } __attribute__ (( packed ));
00290 
00291 /** MBR magic signature */
00292 #define INT13_MBR_MAGIC 0xaa55
00293 
00294 /** A floppy disk geometry */
00295 struct int13_fdd_geometry {
00296         /** Number of tracks */
00297         uint8_t tracks;
00298         /** Number of heads and sectors per track */
00299         uint8_t heads_spt;
00300 };
00301 
00302 /** Define a floppy disk geometry */
00303 #define INT13_FDD_GEOMETRY( cylinders, heads, sectors )                 \
00304         {                                                               \
00305                 .tracks = (cylinders),                                  \
00306                 .heads_spt = ( ( (heads) << 6 ) | (sectors) ),          \
00307         }
00308 
00309 /** Get floppy disk number of cylinders */
00310 #define INT13_FDD_CYLINDERS( geometry ) ( (geometry)->tracks )
00311 
00312 /** Get floppy disk number of heads */
00313 #define INT13_FDD_HEADS( geometry ) ( (geometry)->heads_spt >> 6 )
00314 
00315 /** Get floppy disk number of sectors per track */
00316 #define INT13_FDD_SECTORS( geometry ) ( (geometry)->heads_spt & 0x3f )
00317 
00318 /** A floppy drive parameter table */
00319 struct int13_fdd_parameters {
00320         uint8_t step_rate__head_unload;
00321         uint8_t head_load__ndma;
00322         uint8_t motor_off_delay;
00323         uint8_t bytes_per_sector;
00324         uint8_t sectors_per_track;
00325         uint8_t gap_length;
00326         uint8_t data_length;
00327         uint8_t format_gap_length;
00328         uint8_t format_filler;
00329         uint8_t head_settle_time;
00330         uint8_t motor_start_time;
00331 } __attribute__ (( packed ));
00332 
00333 #endif /* INT13_H */