int 0x13, AH 0x02

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator: Moderators

Post Reply
Posts: 2
Joined: Tue Jul 24, 2018 11:14 pm

int 0x13, AH 0x02

Post by martin » Sun Aug 05, 2018 9:50 pm


I ran into the issue I'm not able to find out the root cause of. I'd appreciate if somebody can help.
I'm reading the disk partition using the int 0x13 service 02 sector by sector.

Virtual disk parameters: 20MB, MBR layout with one FAT16 partition, start: 0/1/1, end: 318/01/63 , sectors per track: 63, heads per cylinder: 2, sector size: 512, cluster size: 4.

I noticed that if I specify to read only one sector (AX: 0x0201) and go beyond the disk offset 0xfe00 (first fail at CHS 1/0/1) I start seeing weird behavior. No error is indicated (AH = 0 after int 0x13) but I start reading back 0s. ES:BX is set to write to the same location all the time, buffer doesn't grow out of the segment, etc.

I'm attaching my code too:
Just before call AX = 0; CX = -1, ES:BX = 0x7c0:0200 (phys 0x7e00)

Code: Select all

        ; Reads sectors into the buffer. Requires following arguments:
        ;       AX:     starting sector for read
        ;       CX:     sectors to read
        ;       ES:BX   buffer to read to
        mov di, HDD_RETRY_SECTOR_READ
        inc cx          ; XXX: debug
        push cx
        push ax
        call lba2chs
                                                ; BIOS call 0x13, function: AH = 0x02 (read sectors from drive)
        mov ch, byte [chs_track]                ;       CH:     cylinder
        mov cl, byte [chs_sector]               ;       CL:     sector
        mov dh, byte [chs_head]                 ;       DH:     head
        mov dl, byte [bsDriveNumber]            ;       DL:     drive
        mov ax, 0x0201                          ;       AL:     sectors to read
        int 0x13

        jnc .ok
        xor ax,ax                               ; BIOS call 0x13, function: AH: 0 = reset disk
        int 0x13

        pop ax
        pop cx
        dec di                                  ; retry till we don't reach the HDD_RETRY_SECTOR_READ
        jnz .retry
        lea si, [rdf]
        call puts16
        jmp fatal                               ; fatal error, reboot

        lea si, [msg_dot]
        call puts16

        pop ax
        pop cx
        inc ax
        ; debug
        ; add bx, word [bpbBytesPerSector]
        times 4 nop

        loop .freshread

Btw. many thanks for the OS dev series.

User avatar
Site Admin
Posts: 465
Joined: Sat Oct 20, 2007 7:58 pm

Re: int 0x13, AH 0x02

Post by Mike » Sat Jun 01, 2019 3:01 am


There is a known error in the original implementation of readSectors where BX may overflow. The following modifications will resolve it:

Code: Select all

   ; go to following instruction in your code:
   add bx, WORD [bpbBytesPerSector]
   ; ...and use the below code right after above instruction:
   jnc .ready
     mov dx, es
     add dh, 0x10
     mov es, dx
     inc ax
     loop .MAIN
However, for hard disks, you really should be using the extended read functions -- int 13h function 42h. Please see our fat32 boot record here for a working example of its use.

Post Reply