Bietje
Bietje

Reputation: 51

bios int 0x13 fails without error

I'm writing a bootloader for educational use and it goes quit well. But when I tried to boot on a real machine my disk read code fails to load some sectors. No error code is given nor is the CF set. It also returns 1 in al which means that 1 sector has been read (which should be correct). But when I try to jump to the loaded sector it just hangs and does nothing.. The first stage prints an A which the second stage overwrites with an F. Only the A is shown when you boot with real hardware. So the sector is not in memory where it should be..

This is my MBR:

LOADOFF equ 0x7C00
BUFFER equ 0x600

[bits 16]
[org 0x7c00]

jmp _start
nop 
    bootdisk db 0

_start: ; entry point
    jmp 0x0:.flush
.flush:
    xor ax, ax
    mov ds, ax
    mov es, ax
    cli
    mov ss, ax
    mov sp, LOADOFF     ; stack setup
    sti

    mov [bootdisk], dl ; boot drive number given by the bios in dl

    mov si, migrate ; move the code below to the buffer
    mov di, BUFFER
    mov cx, 256
    cld
    rep
    movsw

    jmp 0x0:BUFFER ;get my ass in the buffer
migrate:

.reset:
    xor ax, ax      ; reset the disk
    mov dl, [bootdisk]
    int 0x13
    jc .reset

.read:
    mov ah, 0x2
    mov al, 1 ; read 1 sector
    xor cx, cx ; cylinder 0
    mov cl, 2 ; sector 2
    mov dl, [bootdisk]
    xor dh, dh ; head 0


    ; setup buffer
    xor bx, bx
    mov es, bx
    mov bx, 0x7c00 ; chain load it
    int 0x13
    jc .read

    test ah, ah
    jnz .reset

    cmp al, 0x1 ; is there one and only one sector loaded?
    jne .reset

    mov ax, 0xb800
    mov es, ax
    xor di, di
    mov al, 65 ; capital A
    mov ah, 0xc 
    stosw

;   mov ax, 0x7c0
;   mov es, ax
;   xor di, di
;   
;   mov [es:di], byte 191          ; this code proves that my far jump does its work
;   mov [es:di+1], byte 160       ; if you would like to test, comment it out.
;   mov [es:di+2], byte 128
;   mov [es:di+3], byte 184
;   mov [es:di+4], byte 0
;   mov [es:di+5], byte 176
;   mov [es:di+6], byte  142
;   mov [es:di+7], byte 192
;   mov [es:di+8], byte 184
;   mov [es:di+9], byte 88
;   mov [es:di+10], byte 14
;   mov [es:di+11], byte 171

    jmp 0x0:0x7c00      ; execute the loaded sector

times 510 - ($ - $$) db 0
dw 0xAA55

ORG 0x7C00
[BITS 16]

Stage 2:

    stage2:
    mov ax, 0xb800
    mov es, ax
    xor di, di
    mov al, 70
    mov ah, 0xc
    stosw
    jmp $

times 512 - ($ - $$) db 0

It works perfectly in kvm, but NOT on real hardware with a real bios. I use an USB flash drive to test boot on real hardware.

Could the problem be the BPB which I do not define at the first bytes of my mbr? I don't think so because I just read raw sectors.. correct me if I'm wrong.

Anyone any clue what it could be?

Thanks

Upvotes: 2

Views: 2020

Answers (1)

Turbo J
Turbo J

Reputation: 7691

Your code tries to load from disk 0 which ist "first floppy drive". Modern HDD (and USB flash disks) ususally are accessed as disk 0x80. So just try

bootdisk db 0x80

in your code.

Upvotes: 2

Related Questions