You must use function 02h if function 42h is not supported for the drive. Most modern boot loaders do this for compatibility reasons.
Ok, because of that I´ve written, that my MBR code is working.
Do you verify that the BIOS extensions are really present?
Same as above and yes I check this in my MBR code.
The logical first conclusion is that you have a bug in your bootsector.
I´ve also come to this conclusion, but it´s not so easy to debug a bootsector on x86 hardware and the point that it works most of the time doesn´t make it easier
Is it possible you could attach the 2 programs for review ?
Yes, but this code is not really commented
MBR code (the include file only declares a structure for an entry in the partition table):
Code: Select all
org 0
include "partition.inc"
;----------------------------
start:
cli
cld
xor di,di
mov ax,07c0h
mov bx,2000h
mov ds,ax
mov es,bx
mov ss,bx
mov sp,di
mov si,di
sti
mov cx,128
rep movsd
jmp 2000h:relocated
;----------------------------
;----------------------------
align 4
relocated:
mov ds,bx
mov es,sp
mov [bootdrv],dl
;----------------------------
load_bootsector:
mov si,1beh
mov cx,5
;----------------------------
; search an active partition
align 4
.loop:
sub cx,1
jz .end_err_active
cmp byte[si],80h
je .found
add si,part_entry.size_t
jmp .loop
;----------------------------
; load the bootsector of the partition
align 4
.found:
;----------------------------
; test if we can use the extension int13h functions
push si
mov ah,0x41
mov bx,0x55AA
int 0x13
pop si
jc .old
mov eax,[si+part_entry.start_lba]
mov [dap.lba],eax
mov si,dap
mov ah,42h
.loop@found@start:
mov dl,[bootdrv]
mov di,3
.loop@found:
pusha
int 13h
popa
jnc .check
dec di
jnz .loop@found
jmp .end_err_disk
;----------------------------
.old:
mov ax,0x201
mov dh,[si+part_entry.beg_head]
mov cx,[si+part_entry.beg_cylsec]
mov bx,0x7c00
jmp .loop@found@start
;----------------------------
; check the signature of the bootsector
.check:
cmp word[es:0x7DFE],0xAA55
jne .end_err_active
;----------------------------
mov dl,[bootdrv]
jmp 0000h:7c00h
;----------------------------
.end_err_disk:
mov si,msg_err_disk
jmp reboot
;----------------------------
.end_err_active:
mov si,msg_err_active
jmp reboot
;----------------------------
.end_err_os:
mov si,msg_err_os
;----------------------------
;----------------------------
reboot:
call print
mov si,msg_err_reboot
call print
xor ax,ax
int 16h
int 19h
;----------------------------
;----------------------------
print:
mov ah,0eh
.loop:
lodsb
test al,al
jz .end
int 10h
jmp .loop
.end:
ret
;----------------------------
align 4
;----------------------------
; data
; vars
bootdrv db 0
dap:
.size db 10h
.reserved db 0
.blocks dw 1
.offset dw 0
.segment dw 0x07C0
.lba dd 63,0
; msgs
msg_err_disk db 'Could not read disk',13,10,0
msg_err_os db 'Operating System missing',13,10,0
msg_err_active db 'Disk not bootable',13,10,0
msg_err_reboot db 'Press any key to reboot',0
times 510-($-$$) db 0
dw 0xAA55
And here is the bootsector (the include declares a structure for the BPB of FAT16):
Code: Select all
org 0
include "fat12_16.inc"
jmp short start
nop
BPB fat12_16_bpb
;----------------------------
align 4
start:
cli
cld
xor di,di
mov ax,0x2000
mov bx,0x1000
mov ds,di
mov sp,di
mov bp,di
mov si,0x7c00
mov cx,128
mov ss,bx
mov es,bx
rep movsd
jmp 0x1000:load_fat
;----------------------------
align 4
load_fat:
push cs
mov es,ax
pop ds
sti
mov word[dap.size],0x1000
; mov word[dap.offset],cx
mov word[dap.segment],ax
; mov dword[dap.lba+4],ecx
mov [bp+BPB.BS_DrvNum],dl
;----------------------------
; FAT start lba= BPB_ResvdSecCnt + BPB_HiddSec
movzx eax,word[bp+BPB.BPB_ResvdSecCnt]
mov cx,word[bp+BPB.BPB_FATSz16]
add eax,dword[bp+BPB.BPB_HiddSec]
push eax
.loop:
push cx
cmp cx,0x7F
jle .do_it
mov cx,0x7F
;----------------------------
; load the FAT
.do_it:
call load_lba
pop cx
sub cx,0x7F
jle load_root_dir
pop eax
push eax
add eax,0x7F
push cx
bsf cx,word[bp+BPB.BPB_BytsPerSec]
mov bx,0x7F
sub cl,4
shl bx,cl
add [dap.segment],bx
pop cx
jmp .loop
;----------------------------
load_root_dir:
;----------------------------
; RootDirSectors= ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec
movzx eax,word[bp+BPB.BPB_BytsPerSec]
mov bx,word[bp+BPB.BPB_RootEntCnt]
bsf cx,ax
dec ax
shl bx,5
add ax,bx
shr ax,cl
push eax
;----------------------------
; StartSector= BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16) + BPB_HiddSec
movzx eax,word[bp+BPB.BPB_FATSz16]
shl ax,1
pop ecx
pop ebx
add eax,ebx
mov dx,0x50
mov ebx,eax
add ebx,ecx
push ebx
;----------------------------
; destination of rootdir
mov word[dap.segment],dx
mov es,dx
;----------------------------
; load the rootdir
call load_lba
;----------------------------
load_loader:
;----------------------------
mov dx,word[bp+BPB.BPB_RootEntCnt]
xor di,di
;----------------------------
; search the rootdir for the loader
align 4
.loop@search_entry:
;----------------------------
; compare the loader name with the actual entry name
push di
mov si,osloader_img
mov cx,11
rep cmpsb
pop di
je .loop@found_entry
dec dx
jnz .loop@next
;----------------------------
.err_loader:
mov si,msg_err_loader
jmp reboot
;----------------------------
; check next entry
align 4
.loop@next:
add di,fat_dir_ent.size_t
jmp .loop@search_entry
;----------------------------
; right entry, so save the cluster
.loop@found_entry:
pop ecx
mov bx,word[es:di+fat_dir_ent.cluster]
;----------------------------
; test if this was the last cluster
align 4
.loop@cluster:
cmp bx,0fff8h
jae .end
;----------------------------
; look if the cluster is above 64KiB
mov si,bx
mov dx,0x2000
shl si,1
jnc .loop@cluster@doit
mov dx,0x3000
;----------------------------
; calc the lba of the actual cluster and get the new cluster
.loop@cluster@doit:
mov fs,dx
mov edx,ecx
sub bx,2
movzx cx,byte[bp+BPB.BPB_SecPerClus]
movzx eax,bx
bsf cx,cx
mov bx,[fs:si]
shl ax,cl
add eax,edx
;----------------------------
; load the cluster and calculate the new segment address of the next cluster
.loop@cluster@load:
push bx
push edx
movzx cx,byte[bp+BPB.BPB_SecPerClus]
call load_lba
bsf cx,word[bp+BPB.BPB_BytsPerSec]
movzx ax,byte[bp+BPB.BPB_SecPerClus]
; sub cl,4
; shl ax,cl
; add [dap.segment],ax
shl ax,cl
add [dap.offset],ax
pop ecx
pop bx
jmp .loop@cluster
;----------------------------
align 4
.end:
mov dl,[bp+BPB.BS_DrvNum]
jmp 0x50:0x0
;----------------------------
;----------------------------
align 4
print:
mov ah,0eh
;----------------------------
.loop:
lodsb
test al,al
jz .end
int 10h
jmp .loop
;----------------------------
.end:
ret
;----------------------------
;----------------------------
; Input:
; EAX - LBA
; CX - # of lbas 2 load
align 4
load_lba:
mov [dap.lba],eax ;save lba to load
mov [dap.blocks],cx ;save # of blocks 2 load
mov si,dap
mov ah,0x42
mov dl,[bp+BPB.BS_DrvNum]
int 13h
jc .end_err
;----------------------------
.end:
ret
;----------------------------
.end_err:
shr ax,8
add al,'A'
mov ah,0x0e
int 0x10
mov si,msg_err_read
;----------------------------
;----------------------------
reboot:
call print
mov si,msg_reboot
call print
xor ax,ax
int 16h
int 19h
;----------------------------
align 4
;----------------------------
; consts
osloader_img db 'OSLOADER '
; msgs
msg_err_read db 'Error reading disk',13,10,0
msg_err_loader db 'OS-Loader not found',13,10,0
msg_reboot db 'Press any key to reboot',0
times 510-($-$$) db 0
dw 0aa55h
;----------------------------
; bss
dap:
.size rb 1
.reserved rb 1
.blocks rw 1
.offset rw 1
.segment rw 1
.lba rd 2