BIOS int13h function 42h problem
BIOS int13h function 42h problem
I´ve written my own MBR and bootsector code. Both are working, but not on all PCs
The problem I have is that my bootsector code doesn´t work on all PCs I tested my code on. The observation I made is, that it seems that server boards don´t like my bootsector code. At the moment I´m testing on an Opteron (Socket 940) board with an AMI BIOS (it could also be that AMI BIOS is the problem, but I don´t really know).
Both, the MBR and the bootsector use funtion 42h to load sectors from disk, but I only have problems with my bootsector. The error code I get is "1" i.e. "invalid function in AH or invalid parameter".
My question now is, does anyone know what the problem could be? For me it makes no sense that it works on most PCs, but not on all (servers or AMI BIOS).
The problem I have is that my bootsector code doesn´t work on all PCs I tested my code on. The observation I made is, that it seems that server boards don´t like my bootsector code. At the moment I´m testing on an Opteron (Socket 940) board with an AMI BIOS (it could also be that AMI BIOS is the problem, but I don´t really know).
Both, the MBR and the bootsector use funtion 42h to load sectors from disk, but I only have problems with my bootsector. The error code I get is "1" i.e. "invalid function in AH or invalid parameter".
My question now is, does anyone know what the problem could be? For me it makes no sense that it works on most PCs, but not on all (servers or AMI BIOS).
Re: BIOS int13h function 42h problem
I think you may be focusing on the wrong part of your test result. Instead of asking why your bootsector works with some bioses and not others, first ask why one of your programs works and not the other. The logical first conclusion is that you have a bug in your bootsector. Is it possible you could attach the 2 programs for review ?FlashBurn wrote:I´ve written my own MBR and bootsector code. Both are working, but not on all PCs
The problem I have is that my bootsector code doesn´t work on all PCs I tested my code on. The observation I made is, that it seems that server boards don´t like my bootsector code. At the moment I´m testing on an Opteron (Socket 940) board with an AMI BIOS (it could also be that AMI BIOS is the problem, but I don´t really know).
Both, the MBR and the bootsector use funtion 42h to load sectors from disk, but I only have problems with my bootsector. The error code I get is "1" i.e. "invalid function in AH or invalid parameter".
My question now is, does anyone know what the problem could be? For me it makes no sense that it works on most PCs, but not on all (servers or AMI BIOS).
If a trainstation is where trains stop, what is a workstation ?
Re: BIOS int13h function 42h problem
You must use function 02h if function 42h is not supported for the drive. Most modern boot loaders do this for compatibility reasons.
If you have seen bad English in my words, tell me what's wrong, please.
Re: BIOS int13h function 42h problem
Ok, because of that I´ve written, that my MBR code is working.You must use function 02h if function 42h is not supported for the drive. Most modern boot loaders do this for compatibility reasons.
Same as above and yes I check this in my MBR code.Do you verify that the BIOS extensions are really present?
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 easierThe logical first conclusion is that you have a bug in your bootsector.
Yes, but this code is not really commentedIs it possible you could attach the 2 programs for review ?
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
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
Re: BIOS int13h function 42h problem
Who did tell about MBR? I meant both kinds of boot loaders (MBR and stage 1). But probably you have problem with FAT16.FlashBurn wrote:Ok, because of that I´ve written, that my
MBR code is working.
If you have seen bad English in my words, tell me what's wrong, please.
Re: BIOS int13h function 42h problem
Ok, I´m booting from a CF-Card. So the BIOS first loads my MBR which uses function 42h to load my bootsector and this is working on all PCs! Because of that I can say that my MBR code is working and this also means the PC has function 42h. I also think that my FAT16 code is working, because I have no problem with not finding something, but only with reading sectors from disk.Who did tell about MBR? I meant both kinds of boot loaders (MBR and stage 1). But probably you have problem with FAT16.
Maybe I should also say that I use the same CF-Card for all PCs I tested this code on, so because of that I can also say my FAT16 code is working.
Re: BIOS int13h function 42h problem
Flashburn, I had a quick look only.
It seems your MBR code checks for the int 13 extension and then uses it if it is present. If it is not present it jmps to .old and uses int 13 func 2. BUT your bootsector code does not check and always uses func 42. Why ?
Maybe this is why MBR works on all machines.
It seems your MBR code checks for the int 13 extension and then uses it if it is present. If it is not present it jmps to .old and uses int 13 func 2. BUT your bootsector code does not check and always uses func 42. Why ?
Maybe this is why MBR works on all machines.
If a trainstation is where trains stop, what is a workstation ?
Re: BIOS int13h function 42h problem
@gerryg400
As I said, I know that the board (we speak of a modern board!) has the function 42h because I know that my MBR does load the bootsector with this function (because I had debug code in my MBR to know which function is used)!
Ok, so now for all, the board supports function 42h and my MBR uses this function to load my bootsector. So the conclusion is that the fault lies in my bootsector, but the point is that this code does work on almost all PCs, but not on a handful (only Server-boards and maybe also only AMIBIOS boards).
I also thought that the problem is that I not zero the DAP memory, but I also did that and it didn´t help.
As I said, I know that the board (we speak of a modern board!) has the function 42h because I know that my MBR does load the bootsector with this function (because I had debug code in my MBR to know which function is used)!
Ok, so now for all, the board supports function 42h and my MBR uses this function to load my bootsector. So the conclusion is that the fault lies in my bootsector, but the point is that this code does work on almost all PCs, but not on a handful (only Server-boards and maybe also only AMIBIOS boards).
I also thought that the problem is that I not zero the DAP memory, but I also did that and it didn´t help.
Re: BIOS int13h function 42h problem
You are setting dap.size wrong. You are putting a word of 0x1000 into the size and reserved bytes.
This will put a 0 into the size byte (which is wrong). And a 0x10 into the reserved byte (which is wrong).
This will put a 0 into the size byte (which is wrong). And a 0x10 into the reserved byte (which is wrong).
Re: BIOS int13h function 42h problem
@bewing
You are my god
This wasn´t the real failure, but it helped me find the real one! The problem was that I not zeroed all the memory of the DAP and this was a problem on some PCs and as I changed my code to zero the memory, I also introduced a bug (the one you just found)
So now it is working on this board and I assume that it also works on the other boards were it wasn´t working.
So thanks!
You are my god
This wasn´t the real failure, but it helped me find the real one! The problem was that I not zeroed all the memory of the DAP and this was a problem on some PCs and as I changed my code to zero the memory, I also introduced a bug (the one you just found)
So now it is working on this board and I assume that it also works on the other boards were it wasn´t working.
So thanks!