Disk access using the BIOS (INT 13h): Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
Arto (talk | contribs)
m →‎Comments: Categorized the article.
m s/dword/uint32_t/g
Line 3: Line 3:
There are two basic INT0x13 calls to use for ATA disk access. One uses Cylinder, Head, Sector addressing, and the other uses LBA addressing. There is a third command to access ATAPI drives using the PACKET command set.
There are two basic INT0x13 calls to use for ATA disk access. One uses Cylinder, Head, Sector addressing, and the other uses LBA addressing. There is a third command to access ATAPI drives using the PACKET command set.


Note: These BIOS INT calls should completely preserve all the registers (except AX). However, some older versions of the Bochs/Qemu BIOS destroyed the upper words of some of the 32bit registers.
Note: These BIOS INT calls should completely preserve all the registers (except AX). However, some older versions of the Bochs/Qemu BIOS destroyed the upper 16-bit values of some of the 32bit registers.


==CHS==
==CHS==
Line 66: Line 66:




To read or write, first you need to set up a "Disk Address Packet Structure" in memory, on a DWORD (4 byte) boundary.
To read or write, first you need to set up a "Disk Address Packet Structure" in memory, on a uint32_t (4 byte) boundary.


* Format of disk address packet:
* Format of disk address packet:
<pre>
<pre>
Offset Size Description
Offset Size Description
0 BYTE size of packet (16 bytes)
0 1 size of packet (16 bytes)
1 BYTE always 0
1 1 always 0
2 WORD number of sectors to transfer (max 127 on some BIOSes)
2 2 number of sectors to transfer (max 127 on some BIOSes)
4 DWORD -> transfer buffer (16 bit segment:16 bit offset) (see note #1)
4 4 -> transfer buffer (16 bit segment:16 bit offset) (see note #1)
8 DWORD starting LBA
8 4 starting LBA
12 DWORD used for upper part of 48 bit LBAs
12 4 used for upper part of 48 bit LBAs
</pre>
</pre>


Notes:
Notes:


(1) The 16 bit segment value ends up at an offset of 6 from the beginning of the structure (i.e., when declaring segment:offset as two separate word-sized fields, place the offset first and then follow with the segment because x86 is little-endian).
(1) The 16 bit segment value ends up at an offset of 6 from the beginning of the structure (i.e., when declaring segment:offset as two separate 16-bit fields, place the offset first and then follow with the segment because x86 is little-endian).


(2) If the disk drive itself does not support LBA addressing, the BIOS will automatically convert the LBA to a CHS address for you -- so this function still works.
(2) If the disk drive itself does not support LBA addressing, the BIOS will automatically convert the LBA to a CHS address for you -- so this function still works.


(3) The transfer buffer should be WORD (2 byte) aligned.
(3) The transfer buffer should be 16-bit (2 byte) aligned.