4
votes

I'm working on writing my own bootloader. I'm looking to leverage int 13h,02h to read sectors from the boot drive. I'm referencing https://en.wikipedia.org/wiki/INT_13H for documentation on this bios interrupt.

Most reference code I've found assumes the size of a sector to be exclusively 512 bytes, despite the fact that other sizes exist (non-standard sizes such as 520-byte sectors, and 4096-byte sectors). Some sources I've found seem to suggest that the BIOS will always emulate a sector as 512 bytes no matter the underlying size (LBA and sector size), and some appear to indicate that this is not the case (https://www.reddit.com/r/osdev/comments/ajfmtf/is_the_sector_size_for_bios_int_13h_ah2_always/), though no source I've found provides conclusive documentation supporting this fact.

I understand that I can use int 13h,48h to read information about the drive parameters, however I'm still not sure whether the "sector size" returned by this interrupt will be the one used, or whether the BIOS will automatically emulate 512-byte sectors. In addition to this, int 13h,48h is not guaranteed to be supported on every platform (I believe). The reference linked appears to suggest the latter: "Assume you want to read 16 sectors (= 2000h bytes)".

If possible, I'm looking for the following:

  1. Which sector size is actually used for drives with a non-standard sector size, and concrete documentation that supports this answer.
  2. If the non-standard size is in fact the one used, is there a way to determine this value without relying on int 13h,48h?
2

2 Answers

1
votes

One way to find out would be to look at the code of existing bootloaders (e.g. Linux), because they have to deal with that, too. That said, I'd be really really REALLY surprised if there exists a single harddisk that does not support 512 byte reads, and isn't in that mode by default.

In addition to this, int 13h,48h is not guaranteed to be supported on every platform (I believe).

So I guess the safe way is to try INT 13h,48h; if it's supported, use that value; if that's not supported, assume 512 bytes (because if the BIOS would support other read sizes, it should support INT 13h,48h, too).

non-standard sizes such as 520-byte sectors

I am now programming computers for over 40 years, but I've never seen a single device that uses 520-byte sectors. And while there are retro-computers where you can choose to do whatever you want to your floppy, the PC floppy controller only allows powers of two as sector sizes, like 256, 512, 1024, 2048, 4096, etc. And you cannot change this on harddisks at all.

So I am really curious what device you found that has 520-byte sectors?

1
votes

All the non extended BIOS disk services like Int 13h/AH=2h, Int 13h=AH=3h etc. are all assumed to be 512 byte sectors. There is translation done if the underlying media happens to use a larger disk sector size.

Sector sizes will be a multiple of 512 bytes to be compatible with legacy BIOS. In the early days of the IBM-PC there were some drives that supported esoteric sector sizes but they required using different services provided by a BIOS to utilize or required accessing the drive directly (via IO ports etc). In effect you needed special hardware to use such devices or you need to write code written specifically for those devices.

There are certain kinds of SCSI devices (including SAS SSDs) that use 520 byte sectors at the lowest level but you would usually need to wipe the drive and reformat it to use some standard sector size that is a multiple of 512 bytes to be understood by most software and OSes. This usually involves issuing SCSI commands to the drive directly. In Linux sg_format can be used to do this kind of low level operation. These kind of drives generally require specialized controllers as well.

The extended BIOS disk services like Int 13h/AH=42h and Int 13h/AH=43h do not make any such assumption that a sector size is fixed at 512 bytes. On any kind of drive that supports extended disk BIOS services you can query the drive parameters to determine the disk sector size.

If a drive is found to support extended BIOS disk services, you can determine the sector size when your bootloader is running. See the additional notes about how to check if a BIOS and the drive supports these extensions. If the BIOS and drive does support them then you can use Int 13h/AH=48h to query the disk sector size:

IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS
AH = 48h
DL = drive (80h-FFh)
DS:SI -> buffer for drive parameters (see #00273)

Return:
CF clear if successful
AH = 00h
DS:SI buffer filled
CF set on error
AH = error code

[snip]

Format of IBM/MS INT 13 Extensions drive parameters:

Offset  Size    Description     (Table 00273)
00h    WORD    (call) size of buffer
(001Ah for v1.x, 001Eh for v2.x, 42h for v3.0)
(ret) size of returned data
02h    WORD    information flags (see #00274)
04h    DWORD   number of physical cylinders on drive
08h    DWORD   number of physical heads on drive
0Ch    DWORD   number of physical sectors per track
10h    QWORD   total number of sectors on drive
**18h    WORD    bytes per sector**
---v2.0+ ---
1Ah    DWORD   -> EDD configuration parameters (see #00278)
FFFFh:FFFFh if not available
---v3.0 ---
1Eh    WORD    signature BEDDh to indicate presence of Device Path info
20h    BYTE    length of Device Path information, including signature and this
byte (24h for v3.0)
21h  3 BYTEs   reserved (0)
24h  4 BYTEs   ASCIZ name of host bus ("ISA" or "PCI")
28h  8 BYTEs   ASCIZ name of interface type
"ATA"
"ATAPI"
"SCSI"
"USB"
"1394" IEEE 1394 (FireWire)
"FIBRE" Fibre Channel
30h  8 BYTEs   Interface Path (see #00275)
38h  8 BYTEs   Device Path (see #00276)
40h    BYTE    reserved (0)
41h    BYTE    checksum of bytes 1Eh-40h (two's complement of sum, which makes
the 8-bit sum of bytes 1Eh-41h equal 00h)

Notice that the disk structure returned includes:

10h    QWORD  total number of sectors on drive

Additional Notes

Int 13h/AH=48h and the other extended disk functions will likely be part of all modern systems that still support legacy BIOSes. Decades ago this may not have been the case. To determine if the BIOS actually supports extended disk BIOS services you can use Int 13/AH=41h/BX=55AAh:

IBM/MS INT 13 Extensions - INSTALLATION CHECK
AH = 41h
BX = 55AAh
DL = drive (80h-FFh)

Return:
CF set on error (extensions not supported)
AH = 01h (invalid function)
CF clear if successful
BX = AA55h if installed
AH = major version of extensions
01h = 1.x
20h = 2.0 / EDD-1.0
21h = 2.1 / EDD-1.1
30h = EDD-3.0
AL = internal use
CX = API subset support bitmap (see #00271)
DH = extension version (v2.0+ ??? -- not present in 1.x)

If you use this BIOS service and the value returned in BX = AA55h then the BIOS supports disk extensions. If it doesn't you have to fall back to using the non-extended disk functions using CHS addressing. If the BIOS does support extended disk services, it doesn't mean the disk you are checking actually supports it! Most floppy disks do not support extended BIOS disk services even though the BIOS itself does.

That is why you need to also check the Carry Flag (CF) that is returned to see if the disk extensions are supported on the drive you are interested in. If they are not supported you would have to fall back to non-extended BIOS disk services using CHS addressing, otherwise you are free to use the extended disk BIOS services on the drive.

Once you have determine a drive supports extended BIOS disk services then you can use Int 13h/AH=48h as discussed in the first section of this answer to determine the sector size.