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 ); 00011 00012 #include <stdint.h> 00013 #include <gpxe/list.h> 00014 #include <realmode.h> 00015 00016 struct block_device; 00017 00018 /** 00019 * @defgroup int13ops INT 13 operation codes 00020 * @{ 00021 */ 00022 00023 /** Reset disk system */ 00024 #define INT13_RESET 0x00 00025 /** Get status of last operation */ 00026 #define INT13_GET_LAST_STATUS 0x01 00027 /** Read sectors */ 00028 #define INT13_READ_SECTORS 0x02 00029 /** Write sectors */ 00030 #define INT13_WRITE_SECTORS 0x03 00031 /** Get drive parameters */ 00032 #define INT13_GET_PARAMETERS 0x08 00033 /** Get disk type */ 00034 #define INT13_GET_DISK_TYPE 0x15 00035 /** Extensions installation check */ 00036 #define INT13_EXTENSION_CHECK 0x41 00037 /** Extended read */ 00038 #define INT13_EXTENDED_READ 0x42 00039 /** Extended write */ 00040 #define INT13_EXTENDED_WRITE 0x43 00041 /** Get extended drive parameters */ 00042 #define INT13_GET_EXTENDED_PARAMETERS 0x48 00043 /** Get CD-ROM status / terminate emulation */ 00044 #define INT13_CDROM_STATUS_TERMINATE 0x4b 00045 00046 /** @} */ 00047 00048 /** 00049 * @defgroup int13status INT 13 status codes 00050 * @{ 00051 */ 00052 00053 /** Operation completed successfully */ 00054 #define INT13_STATUS_SUCCESS 0x00 00055 /** Invalid function or parameter */ 00056 #define INT13_STATUS_INVALID 0x01 00057 /** Read error */ 00058 #define INT13_STATUS_READ_ERROR 0x04 00059 /** Write error */ 00060 #define INT13_STATUS_WRITE_ERROR 0xcc 00061 00062 /** @} */ 00063 00064 /** Block size for non-extended INT 13 calls */ 00065 #define INT13_BLKSIZE 512 00066 00067 /** An INT 13 emulated drive */ 00068 struct int13_drive { 00069 /** List of all registered drives */ 00070 struct list_head list; 00071 00072 /** Underlying block device */ 00073 struct block_device *blockdev; 00074 00075 /** BIOS in-use drive number (0x80-0xff) */ 00076 unsigned int drive; 00077 /** BIOS natural drive number (0x80-0xff) 00078 * 00079 * This is the drive number that would have been assigned by 00080 * 'naturally' appending the drive to the end of the BIOS 00081 * drive list. 00082 * 00083 * If the emulated drive replaces a preexisting drive, this is 00084 * the drive number that the preexisting drive gets remapped 00085 * to. 00086 */ 00087 unsigned int natural_drive; 00088 00089 /** Number of cylinders 00090 * 00091 * The cylinder number field in an INT 13 call is ten bits 00092 * wide, giving a maximum of 1024 cylinders. Conventionally, 00093 * when the 7.8GB limit of a CHS address is exceeded, it is 00094 * the number of cylinders that is increased beyond the 00095 * addressable limit. 00096 */ 00097 unsigned int cylinders; 00098 /** Number of heads 00099 * 00100 * The head number field in an INT 13 call is eight bits wide, 00101 * giving a maximum of 256 heads. However, apparently all 00102 * versions of MS-DOS up to and including Win95 fail with 256 00103 * heads, so the maximum encountered in practice is 255. 00104 */ 00105 unsigned int heads; 00106 /** Number of sectors per track 00107 * 00108 * The sector number field in an INT 13 call is six bits wide, 00109 * giving a maximum of 63 sectors, since sector numbering 00110 * (unlike head and cylinder numbering) starts at 1, not 0. 00111 */ 00112 unsigned int sectors_per_track; 00113 00114 /** Status of last operation */ 00115 int last_status; 00116 }; 00117 00118 /** An INT 13 disk address packet */ 00119 struct int13_disk_address { 00120 /** Size of the packet, in bytes */ 00121 uint8_t bufsize; 00122 /** Reserved, must be zero */ 00123 uint8_t reserved; 00124 /** Block count */ 00125 uint16_t count; 00126 /** Data buffer */ 00127 struct segoff buffer; 00128 /** Starting block number */ 00129 uint64_t lba; 00130 /** Data buffer (EDD-3.0 only) */ 00131 uint64_t buffer_phys; 00132 } __attribute__ (( packed )); 00133 00134 /** INT 13 disk parameters */ 00135 struct int13_disk_parameters { 00136 /** Size of this structure */ 00137 uint16_t bufsize; 00138 /** Flags */ 00139 uint16_t flags; 00140 /** Number of cylinders */ 00141 uint32_t cylinders; 00142 /** Number of heads */ 00143 uint32_t heads; 00144 /** Number of sectors per track */ 00145 uint32_t sectors_per_track; 00146 /** Total number of sectors on drive */ 00147 uint64_t sectors; 00148 /** Bytes per sector */ 00149 uint16_t sector_size; 00150 00151 } __attribute__ (( packed )); 00152 00153 /** 00154 * @defgroup int13types INT 13 disk types 00155 * @{ 00156 */ 00157 00158 /** No such drive */ 00159 #define INT13_DISK_TYPE_NONE 0x00 00160 /** Floppy without change-line support */ 00161 #define INT13_DISK_TYPE_FDD 0x01 00162 /** Floppy with change-line support */ 00163 #define INT13_DISK_TYPE_FDD_CL 0x02 00164 /** Hard disk */ 00165 #define INT13_DISK_TYPE_HDD 0x03 00166 00167 /** @} */ 00168 00169 /** 00170 * @defgroup int13flags INT 13 disk parameter flags 00171 * @{ 00172 */ 00173 00174 /** DMA boundary errors handled transparently */ 00175 #define INT13_FL_DMA_TRANSPARENT 0x01 00176 /** CHS information is valid */ 00177 #define INT13_FL_CHS_VALID 0x02 00178 /** Removable drive */ 00179 #define INT13_FL_REMOVABLE 0x04 00180 /** Write with verify supported */ 00181 #define INT13_FL_VERIFIABLE 0x08 00182 /** Has change-line supported (valid only for removable drives) */ 00183 #define INT13_FL_CHANGE_LINE 0x10 00184 /** Drive can be locked (valid only for removable drives) */ 00185 #define INT13_FL_LOCKABLE 0x20 00186 /** CHS is max possible, not current media (valid only for removable drives) */ 00187 #define INT13_FL_CHS_MAX 0x40 00188 00189 /** @} */ 00190 00191 /** 00192 * @defgroup int13exts INT 13 extension flags 00193 * @{ 00194 */ 00195 00196 /** Extended disk access functions supported */ 00197 #define INT13_EXTENSION_LINEAR 0x01 00198 /** Removable drive functions supported */ 00199 #define INT13_EXTENSION_REMOVABLE 0x02 00200 /** EDD functions supported */ 00201 #define INT13_EXTENSION_EDD 0x04 00202 00203 /** @} */ 00204 00205 /** 00206 * @defgroup int13vers INT 13 extension versions 00207 * @{ 00208 */ 00209 00210 /** INT13 extensions version 1.x */ 00211 #define INT13_EXTENSION_VER_1_X 0x01 00212 /** INT13 extensions version 2.0 (EDD-1.0) */ 00213 #define INT13_EXTENSION_VER_2_0 0x20 00214 /** INT13 extensions version 2.1 (EDD-1.1) */ 00215 #define INT13_EXTENSION_VER_2_1 0x21 00216 /** INT13 extensions version 3.0 (EDD-3.0) */ 00217 #define INT13_EXTENSION_VER_3_0 0x30 00218 00219 /** @} */ 00220 00221 /** Bootable CD-ROM specification packet */ 00222 struct int13_cdrom_specification { 00223 /** Size of packet in bytes */ 00224 uint8_t size; 00225 /** Boot media type */ 00226 uint8_t media_type; 00227 /** Drive number */ 00228 uint8_t drive; 00229 /** CD-ROM controller number */ 00230 uint8_t controller; 00231 /** LBA of disk image to emulate */ 00232 uint32_t lba; 00233 /** Device specification */ 00234 uint16_t device; 00235 /** Segment of 3K buffer for caching CD-ROM reads */ 00236 uint16_t cache_segment; 00237 /** Load segment for initial boot image */ 00238 uint16_t load_segment; 00239 /** Number of 512-byte sectors to load */ 00240 uint16_t load_sectors; 00241 /** Low 8 bits of cylinder number */ 00242 uint8_t cyl; 00243 /** Sector number, plus high 2 bits of cylinder number */ 00244 uint8_t cyl_sector; 00245 /** Head number */ 00246 uint8_t head; 00247 } __attribute__ (( packed )); 00248 00249 /** A C/H/S address within a partition table entry */ 00250 struct partition_chs { 00251 /** Head number */ 00252 uint8_t head; 00253 /** Sector number, plus high 2 bits of cylinder number */ 00254 uint8_t cyl_sector; 00255 /** Low 8 bits of cylinder number */ 00256 uint8_t cyl; 00257 } __attribute__ (( packed )); 00258 00259 #define PART_HEAD(chs) ( (chs).head ) 00260 #define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f ) 00261 #define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) ) 00262 00263 /** A partition table entry within the MBR */ 00264 struct partition_table_entry { 00265 /** Bootable flag */ 00266 uint8_t bootable; 00267 /** C/H/S start address */ 00268 struct partition_chs chs_start; 00269 /** System indicator (partition type) */ 00270 uint8_t type; 00271 /** C/H/S end address */ 00272 struct partition_chs chs_end; 00273 /** Linear start address */ 00274 uint32_t start; 00275 /** Linear length */ 00276 uint32_t length; 00277 } __attribute__ (( packed )); 00278 00279 /** A Master Boot Record */ 00280 struct master_boot_record { 00281 uint8_t pad[446]; 00282 /** Partition table */ 00283 struct partition_table_entry partitions[4]; 00284 /** 0x55aa MBR signature */ 00285 uint16_t signature; 00286 } __attribute__ (( packed )); 00287 00288 extern void register_int13_drive ( struct int13_drive *drive ); 00289 extern void unregister_int13_drive ( struct int13_drive *drive ); 00290 extern int int13_boot ( unsigned int drive ); 00291 00292 #endif /* INT13_H */
1.5.7.1