Go to the first, previous, next, last section, table of contents.


INT 13H disk I/O interrupts

In the PC world, living with the BIOS disk interface is definitely a nightmare. This section documents how awful the chaos is and how GRUB deals with the BIOS disks.

CHS addressing and LBA addressing

CHS -- Cylinder/Head/Sector -- is the traditional way to address sectors on a disk. There are at least two types of CHS addressing; the CHS that is used at the INT 13H interface and the CHS that is used at the ATA device interface. In the MFM/RLL/ESDI and early ATA days the CHS used at the INT 13H interface was the same as the CHS used at the device interface.

Today we have CHS translating BIOS types that can use one CHS at the INT 13H interface and a different CHS at the device interface. These two types of CHS will be called the logical CHS or L-CHS and the physical CHS or P-CHS in this section. L-CHS is the CHS used at the INT 13H interface and P-CHS is the CHS used at the device interface.

The L-CHS used at the INT 13 interface allows up to 256 heads, up to 1024 cylinders and up to 63 sectors. This allows support of up to 8GB drives. This scheme started with either ESDI or SCSI adapters many years ago.

The P-CHS used at the device interface allows up to 16 heads up to 65535 cylinders, and up to 63 sectors. This allows access to about 2^26 sectors (32GB) on an ATA device. When a P-CHS is used at the INT 13H interface it is limited to 1024 cylinders, 16 heads and 63 sectors. This is where the old 528MB limit originated.

LBA -- Logical Block Address -- is another way of addressing sectors that uses a simple numbering scheme starting with zero as the address of the first sector on a device. The ATA standard requires that cylinder 0, head 0, sector 1 address the same sector as addressed by LBA 0. LBA addressing can be used at the ATA interface if the ATA device supports it. LBA addressing is also used at the INT 13H interface by the AH=4xH read/write calls.

ATA devices may also support LBA at the device interface. LBA allows access to approximately 2^28 sectors (137GB) on an ATA device.

A SCSI host adapter can convert a L-CHS directly to an LBA used in the SCSI read/write commands. On a PC today, SCSI is also limited to 8GB when CHS addressing is used at the INT 13H interface.

First, all OS's that want to be co-resident with another OS (and that is all of the PC based OS's that we know of) must use INT 13H to determine the capacity of a hard disk. And that capacity information must be determined in L-CHS mode. Why is this? Because:

  1. FDISK and the partition tables are really L-CHS based.
  2. MS/PC DOS uses INT 13H AH=02H and AH=03H to read and write the disk and these BIOS calls are L-CHS based.
  3. The boot processing done by the BIOS is all L-CHS based.

During the boot processing, all of the disk read accesses are done in L-CHS mode via INT 13H and this includes loading the first of the OS's kernel code or boot manager's code.

Second, because there can be multiple BIOS types in any one system, each drive may be under the control of a different type of BIOS. For example, drive 80H (the first hard drive) could be controlled by the original system BIOS, drive 81H (the second drive) could be controlled by a option ROM BIOS and drive 82H (the third drive) could be controlled by a software driver. Also, be aware that each drive could be a different type, for example, drive 80H could be an MFM drive, drive 81H could be an ATA drive, drive 82H could be a SCSI drive.

Third, not all OS's understand or use BIOS drive numbers greater than 81H. Even if there is INT 13H support for drives 82H or greater, the OS may not use that support.

Fourth, the BIOS INT 13H configuration calls are:

AH=08H, Get Drive Parameters
This call is restricted to drives up to 528MB without CHS translation and to drives up to 8GB with CHS translation. For older BIOS with no support for >1024 cylinders or >528MB, this call returns the same CHS as is used at the ATA interface (the P-CHS). For newer BIOS's that do support >1024 cylinders or >528MB, this call returns a translated CHS (the L-CHS). The CHS returned by this call is used by FDISK to build partition records.
AH=41H, Get BIOS Extensions Support
This call is used to determine if the IBM/Microsoft Extensions or if the Phoenix Enhanced INT 13H calls are supported for the BIOS drive number.
AH=48H, Extended Get Drive Parameters
This call is used to determine the CHS geometries, LBA information and other data about the BIOS drive number.

An ATA disk must implement both CHS and LBA addressing and must at any given time support only one P-CHS at the device interface. And, the drive must maintain a strict relationship between the sector addressing in CHS mode and LBA mode. Quoting the ATA-2 document:

LBA = ( (cylinder * heads_per_cylinder + heads )
        * sectors_per_track ) + sector - 1

where heads_per_cylinder and sectors_per_track are the current
translation mode values.

This algorithm can also be used by a BIOS or an OS to convert a L-CHS to an LBA.

This algorithm can be reversed such that an LBA can be converted to a CHS:

cylinder = LBA / (heads_per_cylinder * sectors_per_track)
    temp = LBA % (heads_per_cylinder * sectors_per_track)
    head = temp / sectors_per_track
  sector = temp % sectors_per_track + 1

While most OS's compute disk addresses in an LBA scheme, an OS like DOS must convert that LBA to a CHS in order to call INT 13H.

The basic problem is that there is no requirement that a CHS translating BIOS followed these rules. There are many other algorithms that can be implemented to perform a similar function. Today, there are at least two popular implementations: the Phoenix implementation (described above) and the non-Phoenix implementations. Because a protected mode OS that does not want to use INT 13H must implement the same CHS translation algorithm. If it doesn't, your data gets scrambled.

In the perfect world of tomorrow, maybe only LBA will be used. But today we are faced with the following problems:

These are difficult problems to overcome in today's industry environment. The result: chaos.

INT 13H, AH=0xh interrupt call

Real mode only. These functions are the traditional CHS mode disk interface. GRUB calls them only if LBA mode is not available.

INT 13H, AH=02h reads sectors into memory.

Input: cylinder number in bits 6-7.
AH 02h
AL The number of sectors to read (must be non-zero).
CH Low 8 bits of cylinder number.
CL Sector number in bits 0-5, and high 2 bits of
DH Head number.
DL Drive number (bit 7 set for hard disk).
ES:BX Data buffer.

Output: set for some BIOSes).
CF Set on error.
AH Status.
AL The number of sectors transferred (only valid if CF

INT 13H, AH=03h writes disk sectors.

Input: cylinder number in bits 6-7.
AH 03h
AL The number of sectors to write (must be non-zero).
CH Low 8 bits of cylinder number.
CL Sector number in bits 0-5, and high 2 bits of
DH Head number.
DL Drive number (bit 7 set for hard disk).
ES:BX Data buffer.

Output: set for some BIOSes).
CF Set on error.
AH Status.
AL The number of sectors transferred (only valid if CF

INT 13H, AH=08h returns drive parameters. For systems predating the IBM PC/AT, this call is only valid for hard disks.

Input:
AH 08h
DL Drive number (bit 7 set for hard disk).

Output: of maximum cylinder number in bits 6-7.
CF Set on error.
AH 0.
AL 0 on at least some BIOSes.
BL Drive type (AT/PS2 floppies only).
CH Low 8 bits of maximum cylinder number.
CL Maximum sector number in bits 0-5, and high 2 bits
DH Maximum head number.
DL The number of drives.
ES:DI Drive parameter table (floppies only).

INT 13H, AH=4xh interrupt call

Real mode only. These functions are IBM/MS INT 13 Extensions to support LBA mode. GRUB uses them if available so that it can read/write over 8GB area.

INT 13, AH=41h checks if LBA is supported.

Input:
AH 41h.
BX 55AAh.
DL Drive number.

Output: 2.0 / EDD-1.0, 21h for 2.1 / EDD-1.1 and 30h for EDD-3.0) if successful, otherwise 01h (the error code of invalid function).
CF Set on error.
AH Major version of extensions (10h for 1.x, 20h for
BX AA55h if installed.
AL Internal use.
CX API subset support bitmap (see below).
DH Extension version.

The bitfields for the API subset support bitmap are(11): supported. 49h, INT 15H, AH=52h) supported. supported.
Bit(s) Description
0 Extended disk access functions (AH=42h-44h, 47h, 48h)
1 Removable drive controller functions (AH=45h, 46h, 48h,
2 Enhanced disk drive (EDD) functions (AH=48h, 4Eh)
3-15 Reserved (0).

INT 13, AH=42h reads sectors into memory.

Input:
AH 42h.
DL Drive number.
DS:SI Disk Address Packet (see below).

Output:
CF Set on error.
AH 0 if successful, otherwise error code.

The format of Disk Address Packet is: Phoenix EDD).
Offset (hex) Size (byte) Description
00 1 10h (The size of packet).
01 1 Reserved (0).
02 2 The number of blocks to transfer (max 007F for
04 4 Transfer buffer (SEGMENT:OFFSET).
08 8 Starting absolute block number.

INT 13, AH=43h writes disk sectors.

Input: flag for verify write and other bits are reserved (0). In version 2.1, 00h and 01h indicates write without verify, and 02h indicates write with verify.
AH 43h.
AL Write flags (In version 1.0 and 2.0, bit 0 is the
DL Drive number.
DS:SI Disk Address Packet (see above).

Output:
CF Set on error.
AH 0 if successful, otherwise error code.

INT 13, AH=48h returns drive parameters. GRUB only makes use of the total number of sectors, and ignore the CHS information, because only L-CHS makes sense. See section CHS addressing and LBA addressing, for more information.

Input:
AH 48h.
DL Drive number.
DS:SI Buffer for drive parameters (see below).

Output:
CF Set on error.
AH 0 if successful, otherwise error code.

The format of drive parameters is: set to the maximum buffer size, at least 1Ah. The size actually filled is returned (1Ah for version 1.0, 1Eh for 2.x and 42h for 3.0). information. signature and this byte (24h for version 3.0). `ATAPI', `SCSI', `USB', `1394' or `FIBRE'). which makes the 8 bit sum of bytes 1Eh-41h equal to 00h).
Offset (hex) Size (byte) Description
00 2 The size of buffer. Before calling this function,
02 2 Information flags (see below).
04 4 The number of physical cylinders.
08 4 The number of physical heads.
0C 4 The number of physical sectors per track.
10 8 The total number of sectors.
18 2 The bytes per sector.
v2.0 and later
1A 4 EDD configuration parameters.
v3.0
1E 2 Signature BEDD to indicate presence of Device Path
20 1 The length of Device Path information, including
21 3 Reserved (0).
24 4 ASCIZ name of host bus (`ISA' or `PCI').
28 8 ASCIZ name of interface type (`ATA',
30 8 Interface Path.
38 8 Device Path.
40 1 Reserved (0).
41 1 Checksum of bytes 1Eh-40h (2's complement of sum,

The information flags are: removable). current media.
Bit(s) Description
0 DMA boundary errors handles transparently.
1 CHS information is valid.
2 Removable drive.
3 Write with verify supported.
4 Drive has change-line support (required if drive is
5 Drive can be locked (required if drive is removable).
6 CHS information set to maximum supported values, not
7-15 Reserved (0).


Go to the first, previous, next, last section, table of contents.