1 #ifndef INT13_H 2 #define INT13_H 3 4 /** @file 5 * 6 * INT 13 emulation 7 * 8 */ 9 10 FILE_LICENCE ( GPL2_OR_LATER ); 11 12 #include <stdint.h> 13 #include <gpxe/list.h> 14 #include <realmode.h> 15 16 struct block_device; 17 18 /** 19 * @defgroup int13ops INT 13 operation codes 20 * @{ 21 */ 22 23 /** Reset disk system */ 24 #define INT13_RESET 0x00 25 /** Get status of last operation */ 26 #define INT13_GET_LAST_STATUS 0x01 27 /** Read sectors */ 28 #define INT13_READ_SECTORS 0x02 29 /** Write sectors */ 30 #define INT13_WRITE_SECTORS 0x03 31 /** Get drive parameters */ 32 #define INT13_GET_PARAMETERS 0x08 33 /** Get disk type */ 34 #define INT13_GET_DISK_TYPE 0x15 35 /** Extensions installation check */ 36 #define INT13_EXTENSION_CHECK 0x41 37 /** Extended read */ 38 #define INT13_EXTENDED_READ 0x42 39 /** Extended write */ 40 #define INT13_EXTENDED_WRITE 0x43 41 /** Get extended drive parameters */ 42 #define INT13_GET_EXTENDED_PARAMETERS 0x48 43 /** Get CD-ROM status / terminate emulation */ 44 #define INT13_CDROM_STATUS_TERMINATE 0x4b 45 46 /** @} */ 47 48 /** 49 * @defgroup int13status INT 13 status codes 50 * @{ 51 */ 52 53 /** Operation completed successfully */ 54 #define INT13_STATUS_SUCCESS 0x00 55 /** Invalid function or parameter */ 56 #define INT13_STATUS_INVALID 0x01 57 /** Read error */ 58 #define INT13_STATUS_READ_ERROR 0x04 59 /** Write error */ 60 #define INT13_STATUS_WRITE_ERROR 0xcc 61 62 /** @} */ 63 64 /** Block size for non-extended INT 13 calls */ 65 #define INT13_BLKSIZE 512 66 67 /** An INT 13 emulated drive */ 68 struct int13_drive { 69 /** List of all registered drives */ 70 struct list_head list; 71 72 /** Underlying block device */ 73 struct block_device *blockdev; 74 75 /** BIOS in-use drive number (0x80-0xff) */ 76 unsigned int drive; 77 /** BIOS natural drive number (0x80-0xff) 78 * 79 * This is the drive number that would have been assigned by 80 * 'naturally' appending the drive to the end of the BIOS 81 * drive list. 82 * 83 * If the emulated drive replaces a preexisting drive, this is 84 * the drive number that the preexisting drive gets remapped 85 * to. 86 */ 87 unsigned int natural_drive; 88 89 /** Number of cylinders 90 * 91 * The cylinder number field in an INT 13 call is ten bits 92 * wide, giving a maximum of 1024 cylinders. Conventionally, 93 * when the 7.8GB limit of a CHS address is exceeded, it is 94 * the number of cylinders that is increased beyond the 95 * addressable limit. 96 */ 97 unsigned int cylinders; 98 /** Number of heads 99 * 100 * The head number field in an INT 13 call is eight bits wide, 101 * giving a maximum of 256 heads. However, apparently all 102 * versions of MS-DOS up to and including Win95 fail with 256 103 * heads, so the maximum encountered in practice is 255. 104 */ 105 unsigned int heads; 106 /** Number of sectors per track 107 * 108 * The sector number field in an INT 13 call is six bits wide, 109 * giving a maximum of 63 sectors, since sector numbering 110 * (unlike head and cylinder numbering) starts at 1, not 0. 111 */ 112 unsigned int sectors_per_track; 113 114 /** Status of last operation */ 115 int last_status; 116 }; 117 118 /** An INT 13 disk address packet */ 119 struct int13_disk_address { 120 /** Size of the packet, in bytes */ 121 uint8_t bufsize; 122 /** Reserved, must be zero */ 123 uint8_t reserved; 124 /** Block count */ 125 uint16_t count; 126 /** Data buffer */ 127 struct segoff buffer; 128 /** Starting block number */ 129 uint64_t lba; 130 /** Data buffer (EDD-3.0 only) */ 131 uint64_t buffer_phys; 132 } __attribute__ (( packed )); 133 134 /** INT 13 disk parameters */ 135 struct int13_disk_parameters { 136 /** Size of this structure */ 137 uint16_t bufsize; 138 /** Flags */ 139 uint16_t flags; 140 /** Number of cylinders */ 141 uint32_t cylinders; 142 /** Number of heads */ 143 uint32_t heads; 144 /** Number of sectors per track */ 145 uint32_t sectors_per_track; 146 /** Total number of sectors on drive */ 147 uint64_t sectors; 148 /** Bytes per sector */ 149 uint16_t sector_size; 150 151 } __attribute__ (( packed )); 152 153 /** 154 * @defgroup int13types INT 13 disk types 155 * @{ 156 */ 157 158 /** No such drive */ 159 #define INT13_DISK_TYPE_NONE 0x00 160 /** Floppy without change-line support */ 161 #define INT13_DISK_TYPE_FDD 0x01 162 /** Floppy with change-line support */ 163 #define INT13_DISK_TYPE_FDD_CL 0x02 164 /** Hard disk */ 165 #define INT13_DISK_TYPE_HDD 0x03 166 167 /** @} */ 168 169 /** 170 * @defgroup int13flags INT 13 disk parameter flags 171 * @{ 172 */ 173 174 /** DMA boundary errors handled transparently */ 175 #define INT13_FL_DMA_TRANSPARENT 0x01 176 /** CHS information is valid */ 177 #define INT13_FL_CHS_VALID 0x02 178 /** Removable drive */ 179 #define INT13_FL_REMOVABLE 0x04 180 /** Write with verify supported */ 181 #define INT13_FL_VERIFIABLE 0x08 182 /** Has change-line supported (valid only for removable drives) */ 183 #define INT13_FL_CHANGE_LINE 0x10 184 /** Drive can be locked (valid only for removable drives) */ 185 #define INT13_FL_LOCKABLE 0x20 186 /** CHS is max possible, not current media (valid only for removable drives) */ 187 #define INT13_FL_CHS_MAX 0x40 188 189 /** @} */ 190 191 /** 192 * @defgroup int13exts INT 13 extension flags 193 * @{ 194 */ 195 196 /** Extended disk access functions supported */ 197 #define INT13_EXTENSION_LINEAR 0x01 198 /** Removable drive functions supported */ 199 #define INT13_EXTENSION_REMOVABLE 0x02 200 /** EDD functions supported */ 201 #define INT13_EXTENSION_EDD 0x04 202 203 /** @} */ 204 205 /** 206 * @defgroup int13vers INT 13 extension versions 207 * @{ 208 */ 209 210 /** INT13 extensions version 1.x */ 211 #define INT13_EXTENSION_VER_1_X 0x01 212 /** INT13 extensions version 2.0 (EDD-1.0) */ 213 #define INT13_EXTENSION_VER_2_0 0x20 214 /** INT13 extensions version 2.1 (EDD-1.1) */ 215 #define INT13_EXTENSION_VER_2_1 0x21 216 /** INT13 extensions version 3.0 (EDD-3.0) */ 217 #define INT13_EXTENSION_VER_3_0 0x30 218 219 /** @} */ 220 221 /** Bootable CD-ROM specification packet */ 222 struct int13_cdrom_specification { 223 /** Size of packet in bytes */ 224 uint8_t size; 225 /** Boot media type */ 226 uint8_t media_type; 227 /** Drive number */ 228 uint8_t drive; 229 /** CD-ROM controller number */ 230 uint8_t controller; 231 /** LBA of disk image to emulate */ 232 uint32_t lba; 233 /** Device specification */ 234 uint16_t device; 235 /** Segment of 3K buffer for caching CD-ROM reads */ 236 uint16_t cache_segment; 237 /** Load segment for initial boot image */ 238 uint16_t load_segment; 239 /** Number of 512-byte sectors to load */ 240 uint16_t load_sectors; 241 /** Low 8 bits of cylinder number */ 242 uint8_t cyl; 243 /** Sector number, plus high 2 bits of cylinder number */ 244 uint8_t cyl_sector; 245 /** Head number */ 246 uint8_t head; 247 } __attribute__ (( packed )); 248 249 /** A C/H/S address within a partition table entry */ 250 struct partition_chs { 251 /** Head number */ 252 uint8_t head; 253 /** Sector number, plus high 2 bits of cylinder number */ 254 uint8_t cyl_sector; 255 /** Low 8 bits of cylinder number */ 256 uint8_t cyl; 257 } __attribute__ (( packed )); 258 259 #define PART_HEAD(chs) ( (chs).head ) 260 #define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f ) 261 #define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) ) 262 263 /** A partition table entry within the MBR */ 264 struct partition_table_entry { 265 /** Bootable flag */ 266 uint8_t bootable; 267 /** C/H/S start address */ 268 struct partition_chs chs_start; 269 /** System indicator (partition type) */ 270 uint8_t type; 271 /** C/H/S end address */ 272 struct partition_chs chs_end; 273 /** Linear start address */ 274 uint32_t start; 275 /** Linear length */ 276 uint32_t length; 277 } __attribute__ (( packed )); 278 279 /** A Master Boot Record */ 280 struct master_boot_record { 281 uint8_t pad[446]; 282 /** Partition table */ 283 struct partition_table_entry partitions[4]; 284 /** 0x55aa MBR signature */ 285 uint16_t signature; 286 } __attribute__ (( packed )); 287 288 extern void register_int13_drive ( struct int13_drive *drive ); 289 extern void unregister_int13_drive ( struct int13_drive *drive ); 290 extern int int13_boot ( unsigned int drive ); 291 292 #endif /* INT13_H */ 293