This article needs additional citations for verification .(September 2010) |
INT 13h is shorthand for BIOS interrupt call 13 hex , the 20th interrupt vector in an x86-based (IBM PC-descended) computer system. The BIOS typically sets up a real mode interrupt handler at this vector that provides sector-based hard disk and floppy disk read and write services using cylinder-head-sector (CHS) addressing. Modern PC BIOSes also include INT 13h extension functions, originated by IBM and Microsoft in 1992, that provide those same disk access services using 64-bit LBA addressing; with minor additions, these were quasi-standardized by Phoenix Technologies and others as the EDD (Enhanced Disk Drive) BIOS extensions.
INT is an x86 instruction that triggers a software interrupt, and 13hex is the interrupt number (as a hexadecimal value) being called.
Modern computers come with both BIOS INT 13h and UEFI functionality that provides the same services and more, with the exception of UEFI Class 3 that completely removes CSM thus lacks INT 13h and other interrupts. Typically, UEFI drivers use LBA-addressing instead of CHS-addressing.
Under real mode operating systems, such as DOS, calling INT 13h would jump into the computer's ROM-BIOS code for low-level disk services, which would carry out physical sector-based disk read or write operations for the program. In DOS, it serves as the low-level interface for the built-in block device drivers for hard disks and floppy disks. This allows INT 25h and INT 26h to provide absolute disk read/write functions for logical sectors to the FAT file system driver in the DOS kernel, which handles file-related requests through DOS API (INT 21h) functions.
Under protected mode operating systems, such as Microsoft Windows NT derivatives (e.g. NT4, 2000, XP, and Server 2003) and Linux with dosemu, the OS intercepts the call and passes it to the operating system's native disk I/O mechanism. Windows 9x and Windows for Workgroups 3.11 also bypass BIOS routines when using 32-bit Disk Access. Besides performing low-level disk access, INT 13h calls and related BIOS data structures also provide information about the types and capacities of disks (or other DASD devices) attached to the system; when a protected-mode OS boots, it may use that information from the BIOS to enumerate disk hardware so that it (the OS) can load and configure appropriate disk I/O drivers.
The original BIOS real-mode INT 13h interface supports drives of sizes up to about 8 GB using what is commonly referred to as physical CHS addressing. This limit originates from the hardware interface of the IBM PC/XT disk hardware. The BIOS used the cylinder-head-sector (CHS) address given in the INT 13h call, and transferred it directly to the hardware interface. A lesser limit, about 504 MB, was imposed by the combination of CHS addressing limits used by the BIOS and those used by ATA hard disks, which are dissimilar. When the CHS addressing limits of both the BIOS and ATA are combined (i.e. when they are applied simultaneously), the number of 512-byte sectors that can be addressed represent a total of about 504 MB.
The 504 MB limit was overcome using CHS translation, a technique by which the BIOS would simulate a fictitious CHS geometry at the INT 13h interface, while communicating with the ATA drive using its native logical CHS geometry. (By the time the 504 MB barrier was being approached, ATA disks had long before ceased to present their real physical geometry parameters at the external ATA interface.) Translation allows the BIOS, still using CHS addressing, to effectively address ATA disks with sizes up to 8064 MB, the native capacity of the BIOS CHS interface alone. (The ATA interface has a much larger native CHS addressing capacity, so once the "interference" of the CHS limits of BIOS and ATA was resolved by addressing, only the smaller limitation of the BIOS was significant.) CHS translation is sometimes referred to as logical CHS addressing, but that is actually a misnomer since by the time of this BIOS development, ATA CHS addresses were already logical, not physical. The 8064 MB limit originates from a combination of the register value based calling convention used in the INT 13h interface and the goal of maintaining backward compatibility—dictating that the format or size of CHS addresses passed to INT 13h could not be changed to add more bits to one of the fields, e.g. the Cylinder-number field. This limit uses 1024 cylinders, 256 heads, 63 sectors, and 512 byte blocks, allowing exactly 7.875 GiB of addressing (1024 × 256 × 63 × 512 bytes). There were briefly a number of BIOSes that offered incompatible versions of this interface—for example, AWARD AT BIOS and AMI 386sx BIOS have been extended to handle up to 4096 cylinders by placing bits 10 and 11 of the cylinder number into bits 6 and 7 of register DH.
All versions of MS-DOS, (including MS-DOS 7 and Windows 95) have a bug which prevents booting disk drives with 256 heads (register value 0xFF), so many modern BIOSes provide CHS translation mappings with at most 255 (0xFE) heads, [1] [2] thus reducing the total addressable space to exactly 8032.5 MiB (approx 7.844 GiB). [3]
To support addressing of even larger disks, an interface known as INT 13h Extensions was introduced by IBM and Microsoft, then later re-published and slightly extended by Phoenix Technologies as part of BIOS Enhanced Disk Drive Services (EDD). [4] [5] It defines new functions within the INT 13h service, all having function numbers greater than 40h, that use 64-bit logical block addressing (LBA), which allows addressing up to 8 ZiB. (An ATA drive can also support 28-bit or 48-bit LBA which allows up to 128 GiB or 128 PiB respectively, assuming a 512-byte sector/block size). This is a "packet" interface, because it uses a pointer to a packet of information rather than the register based calling convention of the original INT 13h interface. This packet is a very simple data structure that contains an interface version, data size, and LBAs. For software backward-compatibility, the extended functions are implemented alongside the original CHS functions, and calls to functions from both sets can be intermixed, even for the same drive, with the caveat that the CHS functions cannot reach past the first 8064 MB of the disk.
Some cache drivers flush their buffers when detecting that DOS is bypassed by directly issuing INT 13h from applications. A dummy read via INT 13h can be used as one of several methods to force cache flushing for unknown caches (e.g. before rebooting). [1] [2]
AMI BIOSes from around 1990–1991 trash word unaligned buffers. Some DOS and terminate-and-stay-resident programs clobber interrupt enabling and registers so PC DOS and MS-DOS install their own filters to prevent this. [6]
DL = 00h | 1st floppy disk ( "drive A:" ) |
DL = 01h | 2nd floppy disk ( "drive B:" ) |
DL = 02h | 3rd floppy disk ( "drive C:" ) |
. . . | |
DL = 7Fh | 128th floppy disk |
DL = 80h | 1st hard disk |
DL = 81h | 2nd hard disk |
DL = 82h | 3rd hard disk |
. . . | |
DL = E0h | CD/DVD[ citation needed ], or 97th hard disk |
. . . | |
DL = FFh | 128th hard disk |
AH = 00h | Reset Disk System | |
AH = 01h | Get Status of Last Drive Operation | |
AH = 02h | Read Sectors From Drive | |
AH = 03h | Write Sectors To Drive | |
AH = 04h | Verify Sectors | |
AH = 05h | Format Track | |
AH = 06h | Format Track Set Bad Sector Flags | |
AH = 07h | Format Drive starting at Track | |
AH = 08h | Read Drive Parameters | |
AH = 09h | HD | Initialize Disk Controller |
AH = 0Ah | HD | Read Long Sectors From Drive |
AH = 0Bh | HD | Write Long Sectors To Drive |
AH = 0Ch | HD | Move Drive Head To Cylinder |
AH = 0Dh | HD | Reset Disk Drives |
AH = 0Eh | PS/2 | Controller Read Test |
AH = 0Fh | PS/2 | Controller Write Test |
AH = 10h | HD | Test Whether Drive Is Ready |
AH = 11h | HD | Recalibrate Drive |
AH = 12h | PS/2 | Controller RAM Test |
AH = 13h | PS/2 | Drive Test |
AH = 14h | HD | Controller Diagnostic |
AH = 15h | Read Drive Type | |
AH = 16h | FD | Detect Media Change |
AH = 17h | FD | Set Media Type For Format (used by DOS versions <= 3.1) |
AH = 18h | FD | Set Media Type For Format (used by DOS versions >= 3.2) |
AH = 19h | Park Heads | |
AH = 41h | EXT | Test Whether Extensions Are Available |
AH = 42h | EXT | Read Sectors From Drive |
AH = 43h | EXT | Write Sectors To Drive |
AH = 44h | EXT | Verify Sectors |
AH = 45h | EXT | Lock/Unlock Drive |
AH = 46h | EXT | Eject Drive |
AH = 47h | EXT | Move Drive Head To Sector |
AH = 48h | EXT | Read Drive Parameters |
AH = 49h | EXT | Detect Media Change |
AH = 4Bh | EXT | Get Drive Emulation Type |
If the second column is empty then the function may be used both for floppy and hard disk.
AH | 00h |
DL | Drive (bit 7 set means reset both hard and floppy disks) |
CF | Set on error |
AH | Return Code |
AH | 01h |
DL | Drive |
Bit 7=0 for floppy drive, bit 7=1 for fixed drive
AH |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||
CF | Set On Error, Clear If No Error |
AH | 02h |
AL | Sectors To Read Count |
CH | Cylinder |
CL | Sector |
DH | Head |
DL | Drive |
ES:BX | Buffer Address Pointer |
CF | Set On Error, Clear If No Error |
AH | Return Code |
AL | Actual Sectors Read Count |
Register CX contains both the cylinder number (10 bits, possible values are 0 to 1023) and the sector number (6 bits, possible values are 1 to 63). Cylinder and Sector bits are numbered below:
CX = ---CH--- ---CL--- cylinder : 76543210 98 sector : 543210
Examples of translation:
CX:=((cylinderand255)shl8)or((cylinderand768)shr2)orsector;cylinder:=((CXand$FF00)shr8)or((CXand$C0)shl2)sector:=CXand63;
Addressing of Buffer should guarantee that the complete buffer is inside the given segment, i.e. ( BX + size_of_buffer ) <= 10000h
. Otherwise the interrupt may fail with some BIOS or hardware versions.
Assume you want to read 16 sectors (= 2000h bytes) and your buffer starts at memory address 4FF00h. Utilizing memory segmentation, there are different ways to calculate the register values, e.g.:
ES = segment = 4F00h BX = offset = 0F00h sum = memory address = 4FF00h would be a good choice because 0F00h + 2000h = 2F00h <= 10000h ES = segment = 4000h BX = offset = FF00h sum = memory address = 4FF00h would not be a good choice because FF00h + 2000h = 11F00h > 10000h
Function 02h of interrupt 13h may only read sectors of the first 16,450,560 sectors of your hard drive, to read sectors beyond the 8 GB limit you should use function 42h of INT 13h Extensions. Another alternate may be DOS interrupt 25h which reads sectors within a partition.
[ORG7c00h]; code starts at 7c00hxorax,ax; make sure ds is set to 0movds,axcld; start putting in values:movah,2h; int13h function 2moval,63; we want to read 63 sectorsmovch,0; from cylinder number 0movcl,2; the sector number 2 - second sector (starts from 1, not 0)movdh,0; head number 0xorbx,bxmoves,bx; es should be 0movbx,7e00h; 512bytes from origin address 7c00hint13hjmp7e00h; jump to the next sector; to fill this sector and make it bootable:times510-($-$$)db0dw0AA55h
After this code section (which the asm file should start with), you may write code and it will be loaded to memory and executed.
Notice how we didn't change dl (the drive). That is because when the computer first loads up, dl is set to the number of the drive that was booted, so assuming we want to read from the drive we booted from, there is no need to change dl.
AH | 03h |
AL | Sectors To Write Count |
CH | Track |
CL | Sector |
DH | Head |
DL | Drive |
ES:BX | Buffer Address Pointer |
CF | Set On Error, Clear If No Error |
AH | Return Code |
AL | Actual Sectors Written Count |
AH | 04h |
AL | Sectors To Verify Count |
CH | Track |
CL | Sector |
DH | Head |
DL | Drive |
ES:BX | Buffer Address Pointer |
CF | Set On Error, Clear If No Error |
AH | Return Code |
AL | Actual Sectors Verified Count |
AH | 05h |
AL | Sectors To Format Count |
CH | Track |
CL | Sector |
DH | Head |
DL | Drive |
ES:BX | Buffer Address Pointer |
Byte | Meaning | Allowable Values |
---|---|---|
1 | Track | |
2 | Head | |
3 | Sector | |
4 | Bytes/Sector | 0=128, 1-256, 2-512, 3-1024 |
CF | Set On Error, Clear If No Error |
AH | Return Code |
AH | 06h |
AL | Interleave |
CH | Track |
CL | Sector |
DH | Head |
DL | Drive |
CF | Set On Error, Clear If No Error |
AH | Return Code |
AH | 07h |
AL | Interleave |
CH | Track |
CL | Sector |
DH | Head |
DL | Drive |
CF | Set On Error, Clear If No Error |
AH | Return Code |
Registers | |
---|---|
AH | 08h = function number for read_drive_parameters |
DL | drive index (e.g. 1st HDD = 80h) |
ES:DI [7] | set to 0000h:0000h to work around some buggy BIOS |
CF | Set On Error, Clear If No Error |
AH | Return Code |
DL | number of hard disk drives |
DH [7] | logical last index of heads = number_of - 1 (because index starts with 0) |
CX | [7:6] [15:8] [7] logical last index of cylinders = number_of - 1 (because index starts with 0) [5:0] [7] logical last index of sectors per track = number_of (because index starts with 1) |
BL [7] | drive type (only AT/PS2 floppies) |
ES:DI [7] | pointer to drive parameter table (only for floppies) |
AH | 09h |
DL | Drive |
CF | Set On Error, Clear If No Error |
AH | Return Code |
The only difference between this function and function 02h (see above) is that function 0Ah reads 516 bytes per sector instead of only 512. The last 4 bytes contains the Error Correction Code (ECC), a checksum of sector data.
Registers | Description |
---|---|
AH | 41h = function number for extensions check [8] |
DL | drive index (e.g. 1st HDD = 80h) |
BX | 55AAh |
Registers | Description |
---|---|
CF | Set On Not Present, Clear If Present |
AH | Error Code or Major Version Number |
BX | AA55h |
CX | Interface support bitmask:
|
Registers | Description | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
AH | 42h = function number for extended read | ||||||||||||||||||
DL | drive index (e.g. 1st HDD = 80h) | ||||||||||||||||||
DS:SI | segment:offset pointer to the DAP, see below
|
Registers | Description |
---|---|
CF | Set On Error, Clear If No Error |
AH | Return Code |
As already stated with int 13h AH=02h, care must be taken to ensure that the complete buffer is inside the given segment, i.e. ( BX + size_of_buffer ) <= 10000h
Registers | Description |
---|---|
AH | 43h = function number for extended write |
AL |
|
DL | drive index (e.g. 1st HDD = 80h) |
DS:SI | segment:offset pointer to the DAP |
Registers | Description |
---|---|
CF | Set On Error, Clear If No Error |
AH | Return Code |
Registers | Description | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
AH | 48h = function number for extended_read_drive_parameters | |||||||||||||||||||||||||||
DL | drive index (e.g. 1st HDD = 80h) | |||||||||||||||||||||||||||
DS:SI | segment:offset pointer to Result Buffer, see below
|
Registers | Description |
---|---|
CF | Set On Error, Clear If No Error |
AH | Return Code |
Physical CHS values of function 48h may/should differ from logical values of function 08h.
Regsiters | Description |
---|---|
AH | 4Bh = get drive emulation type |
AL | 01 |
DL | drive index (e.g. 1st HDD = 80h) |
DS:SI | points to an empty structure for result . must be 13h in size |
Registers | Description | |||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
CF | Set On Error, Clear if No Error | |||||||||||||||||||||||||||||||||||||||||||||||||
AX | Return Code | |||||||||||||||||||||||||||||||||||||||||||||||||
DS:SI | Points to a specification structure
|
Parallel ATA (PATA), originally AT Attachment, also known as Integrated Drive Electronics (IDE), is a standard interface designed for IBM PC-compatible computers. It was first developed by Western Digital and Compaq in 1986 for compatible hard drives and CD or DVD drives. The connection is used for storage devices such as hard disk drives, floppy disk drives, optical disc drives, and tape drives in computers.
In computing, BIOS is firmware used to provide runtime services for operating systems and programs and to perform hardware initialization during the booting process. The BIOS firmware comes pre-installed on an IBM PC or IBM PC compatible's system board and exists in some UEFI-based systems to maintain compatibility with operating systems that do not support UEFI native operation. The name originates from the Basic Input/Output System used in the CP/M operating system in 1975. The BIOS originally proprietary to the IBM PC has been reverse engineered by some companies looking to create compatible systems. The interface of that original system serves as a de facto standard.
Disk storage is a data storage mechanism based on a rotating disk. The recording employs various electronic, magnetic, optical, or mechanical changes to the disk's surface layer. A disk drive is a device implementing such a storage mechanism. Notable types are hard disk drives (HDD), containing one or more non-removable rigid platters; the floppy disk drive (FDD) and its removable floppy disk; and various optical disc drives (ODD) and associated optical disc media.
In computing, booting is the process of starting a computer as initiated via hardware such as a button on the computer or by a software command. After it is switched on, a computer's central processing unit (CPU) has no software in its main memory, so some process must load software into memory before it can be executed. This may be done by hardware or firmware in the CPU, or by a separate processor in the computer system.
File Allocation Table (FAT) is a file system developed for personal computers and was the default filesystem for MS-DOS and Windows 9x operating systems. Originally developed in 1977 for use on floppy disks, it was adapted for use on hard disks and other devices. The increase in disk drives capacity required four major variants: FAT12, FAT16, FAT32, and ExFAT. FAT was replaced with NTFS as the default file system on Microsoft operating systems starting with Windows XP. Nevertheless, FAT continues to be used on flash and other solid-state memory cards and modules, many portable and embedded devices because of its compatibility and ease of implementation.
x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.
Disk formatting is the process of preparing a data storage device such as a hard disk drive, solid-state drive, floppy disk, memory card or USB flash drive for initial use. In some cases, the formatting operation may also create one or more new file systems. The first part of the formatting process that performs basic medium preparation is often referred to as "low-level formatting". Partitioning is the common term for the second part of the process, dividing the device into several sub-devices and, in some cases, writing information to the device allowing an operating system to be booted from it. The third part of the process, usually termed "high-level formatting" most often refers to the process of generating a new file system. In some operating systems all or parts of these three processes can be combined or repeated at different levels and the term "format" is understood to mean an operation in which a new disk medium is fully prepared to store files. Some formatting utilities allow distinguishing between a quick format, which does not erase all existing data and a long option that does erase all existing data.
Logical block addressing (LBA) is a common scheme used for specifying the location of blocks of data stored on computer storage devices, generally secondary storage systems such as hard disk drives. LBA is a particularly simple linear addressing scheme; blocks are located by an integer index, with the first block being LBA 0, the second LBA 1, and so on.
The Program Segment Prefix (PSP) is a data structure used in DOS systems to store the state of a program. It resembles the Zero Page in the CP/M operating system. The PSP has the following structure:
SpinRite is a computer program for scanning RAS Random Access Storage devices such as hard disks, reading and rewriting data to resolve and retrieve data that is unreadable by DOS or Windows. The first version was released in 1987 by Steve Gibson. The current version, 6.1, was released in 2024.
BIOS implementations provide interrupts that can be invoked by operating systems and application programs to use the facilities of the firmware on IBM PC compatible computers. Traditionally, BIOS calls are mainly used by DOS programs and some other software such as boot loaders. BIOS runs in the real address mode of the x86 CPU, so programs that call BIOS either must also run in real mode or must switch from protected mode to real mode before calling BIOS and then switching back again. For this reason, modern operating systems that use the CPU in Protected mode or Long mode generally do not use the BIOS interrupt calls to support system functions, although they use the BIOS interrupt calls to probe and initialize hardware during booting. Real mode has the 1MB memory limitation, modern boot loaders use the unreal mode or protected mode to access up to 4GB memory.
Cylinder-head-sector (CHS) is an early method for giving addresses to each physical block of data on a hard disk drive.
An Option ROM for the PC platform is a piece of firmware that resides in ROM on an expansion card, which gets executed to initialize the device and (optionally) add support for the device to the BIOS. In its usual use, it is essentially a driver that interfaces between the BIOS API and hardware. Technically, an option ROM is firmware that is executed by the BIOS after POST and before the BIOS boot process, gaining complete control of the system and being generally unrestricted in what it can do. The BIOS relies on each option ROM to return control to the BIOS so that it can either call the next option ROM or commence the boot process. For this reason, it is possible for an option ROM to keep control and preempt the BIOS boot process. The BIOS generally scans for and initializes option ROMs in ascending address order at 2 KB address intervals within two different address ranges above address C0000h in the conventional (20-bit) memory address space; later systems may also scan additional address ranges in the 24-bit or 32-bit extended address space.
The GUID Partition Table (GPT) is a standard for the layout of partition tables of a physical computer storage device, such as a hard disk drive or solid-state drive, using universally unique identifiers (UUIDs), which are also known as globally unique identifiers (GUIDs). Forming a part of the Unified Extensible Firmware Interface (UEFI) standard, it is nevertheless also used for some BIOSs, because of the limitations of master boot record (MBR) partition tables, which use 32 bits for logical block addressing (LBA) of traditional 512-byte disk sectors.
The Logical Disk Manager (LDM) is an implementation of a logical volume manager for Microsoft Windows NT, developed by Microsoft and Veritas Software. It was introduced with the Windows 2000 operating system, and is supported in Windows XP, Windows Server 2003, Windows Vista, Windows 7, Windows 8, Windows 10 and Windows 11. The MMC-based Disk Management snap-in hosts the Logical Disk Manager. On Windows 8 and Windows Server 2012, Microsoft deprecated LDM in favor of Storage Spaces.
An extended boot record (EBR), or extended partition boot record (EPBR), is a descriptor for a logical partition under the common DOS disk drive partitioning system. In that system, when one partition record entry in the master boot record (MBR) is designated an extended partition, then that partition can be subdivided into a number of logical partitions. The actual structure of that extended partition is described by one or more EBRs, which are located inside the extended partition. The first EBR will always be located on the first sector of the extended partition.
A volume boot record (VBR) is a type of boot sector introduced by the IBM Personal Computer. It may be found on a partitioned data storage device, such as a hard disk, or an unpartitioned device, such as a floppy disk, and contains machine code for bootstrapping programs stored in other parts of the device. On non-partitioned storage devices, it is the first sector of the device. On partitioned devices, it is the first sector of an individual partition on the device, with the first sector of the entire device being a Master Boot Record (MBR) containing the partition table.
C# Open Source Managed Operating System (Cosmos) is a toolkit for building GUI and command-line based operating systems, written mostly in the programming language C# and small amounts of a high-level assembly language named X#. Cosmos is a backronym, in that the acronym was chosen before the meaning. It is open-source software released under a BSD license.
A master boot record (MBR) is a type of boot sector in the first block of partitioned computer mass storage devices like fixed disks or removable drives intended for use with IBM PC-compatible systems and beyond. The concept of MBRs was publicly introduced in 1983 with PC DOS 2.0.
The FAT file system is a file system used on MS-DOS and Windows 9x family of operating systems. It continues to be used on mobile devices and embedded systems, and thus is a well suited file system for data exchange between computers and devices of almost any type and age from 1981 through the present.