Bootsector致命:INT18 BOOT ERROR

时间:2012-10-05 22:36:30

标签: assembly bootstrapper

无法让我的FAT32引导扇区工作。请帮我。我已经尝试了从查看代码到在virtualbox中测试它的所有内容。当我在virtualbox中运行它时,我收到此错误:致命错误:INT18 BOOT ERROR。这是代码:

BITS 16
ORG 0x7C00
jmp START

OEM_ID db “PARADIGM"
BytesPerSector dw 0x0200
SectorsPerCluster db 0x08
ReservedSectors dw 0x0021
TotalFATs db 0x02
MaxRootEntries dw 0x0000
TotalSectorsSmall dw 0x0000
MediaDescriptor db 0xF8
SectorsPerTrack dw 0x003F
SectorsPerHead dw 0x0080
HiddenSectors dd 0x0000003F
TotalSectorsBig dd 0x0040994
BigSectorsPerFAT dd 0x00000778
SectorsPerFAT dd 0x0000101F
Flags dw 0x0000
FSVersion dw 0x0000
RootDirectoryStart dd 0x00000002
FSInfoSector dw 0x0001
BackupBootSector dw 0x0006
times 13 db 0x00
DriveNumber db 0x00
db 0x00
Signature db 0x29
VolumeID dd 0x1F040FD5
VolumeLabel db "PARADIGM_BOOT"
SystemID db "FAT32"

START:
cli
mov ax, 0x0000
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x0000
mov ss, ax
mov sp, 0x0000
sti
mov si, msgLoading
call DisplayMessage
mov cx,  WORD[SectorsPerCluster]
xor ax, ax
mov al, BYTE [TotalFATs]
mul WORD[BigSectorsPerFAT]
add ax, WORD [ReservedSectors]
mov WORD [datasector], ax
xor ax, ax
mov ax, WORD [RootDirectoryStart]
call ClusterLBA
mov bx, 0x0200
call ReadSectors
mov cx, WORD [0x0080]
mov di, 0x0200
.LOOP:
push cx
mov cx, 0x000C
mov si, ImageName
push di
rep cmpsb
pop di
je LOAD_FILE
pop cx
add di, 0x0020
loop .LOOP
jmp FAILURE

LOAD_FILE:
mov si, msgCRLF
call DisplayMessage
mov dx, WORD [di + 0x001A]
mov WORD [cluster], dx
mov ax, 0x0100
mov es, ax
mov bx, 0
xor cx, cx
mov cl, BYTE[SectorsPerCluster]
mov ax, WORD[cluster]
call ClusterLBA
call ReadSectors
jmp DONE

DONE:
mov si, msgCRLF
call DisplayMessage
push WORD 0x0200
push WORD 0x0000
retf

FAILURE:
mov si, msgFailure
call DisplayMessage
mov ah, 0x00
int 0x16
int 0x19

DisplayMessage:
lodsb
or al, al
jz .DONE
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10
jmp DisplayMessage
.DONE:
ret

ReadSectors:
.MAIN:
mov di, 5
.SECTORLOOP:
push ax
push bx
push cx
call LBACHS
mov ah, 0x02
mov al, 0x01
mov ch, BYTE [absoluteTrack]
mov cl, BYTE [absoluteSector]
mov dh, BYTE [absoluteHead]
mov dl, BYTE [DriveNumber]
int 0x13
jnc .SUCCESS
xor ax, ax
int 0x13
dec di
pop cx
pop bx
pop ax
jnz .SECTORLOOP
int 0x18
.SUCCESS:
mov si, msgProgress
call DisplayMessage
pop cx
pop bx
pop ax
add bx, WORD [BytesPerSector]
inc ax
loop .MAIN
ret

ClusterLBA:
sub ax, 0x0002
xor cx, cx
mov cl, BYTE [SectorsPerCluster]
mul cx
add ax, WORD [datasector]
ret

LBACHS:
xor dx, dx
div WORD [SectorsPerTrack]
inc dl
mov BYTE [absoluteSector], dl
xor dx, dx
div WORD [SectorsPerHead]
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret

absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00

datasector dw 0x0000
cluster dw 0x0000
ImageName dw "BOOTLOAD.BIN"
msgLoading db 0x0D, 0x0A, "Loading Boot Image", 0x0D, 0x0A, 0x00
msgCRLF db 0x0D, 0x0A, 0x00
msgProgress db ".", 0x00
msgFailure db 0x0D, 0x0A, "ERROR: Press Any Key to Reboot", 0x00

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

我正在使用iso规范。似乎它没有正确地阅读这些部门。我从Amila Surendra

获得了代码

1 个答案:

答案 0 :(得分:1)

当BIOS无法找到任何要引导的内容时,通常会使用“Int 0x18”。曾几何时,它曾经在ROM中启动BASIC解释器,但现在只显示一条消息。

BIOS检查是否可以读取器件的第一个扇区,以及它是否包含扇区中偏移量0x01FE处的魔术特征0xAA55。没有其他要求 - 该扇区的其余部分可能充满随机字节,导致计算机崩溃,BIOS不关心并将执行它(并且不会显示“Int 0x18”消息)。

您的代码确实包含偏移0x01FE处的魔术签名;因此问题不是你的代码。问题可能在于如何将引导扇区安装到磁盘映像中或者如何配置仿真器。

要检查的事项:

1)模拟器被告知在哪里可以找到磁盘映像(例如,并没有尝试启动完全不同的东西,或者没有被告知从不存在的磁盘启动)

2)模拟器被告知从您设置磁盘映像的任何磁盘驱动器启动(例如,当引导扇区位于硬盘或其他东西时,您没有尝试从软盘启动)

3)磁盘映像采用仿真器所期望的格式。大多数仿真器支持几种不同的磁盘映像格式(VDI,VHD等)。如果磁盘映像是一种格式(例如,仅包含原始扇区数据的固定大小的映像),但仿真器认为它采用不同的格式(例如VDI),那么它可能会导致问题。

4)引导扇区正确安装在磁盘映像中(可以考虑使用“hexdump”之类的工具来检查磁盘映像的第一个扇区)。这可能包括将代码安装为分区的第一个扇区,磁盘的第一个扇区中没有任何内容(请参阅下面的分区信息)。

未来说明:

您的BPB(“BIOS参数块”)看起来像是用于硬盘(不是软盘)。硬盘有不同的大小(通常你不能硬编码像“sectorPerCylinder”这样的东西),这意味着通常你需要编写一个特殊的实用程序来检测正确的值,调整BPB中的值,然后安装修改后的启动扇区。

此外,硬盘通常是分区的。 BIOS(对分区一无所知)加载并启动磁盘上的第一个扇区,第一个扇区(通常称为MBR或主引导记录)包含检查分区表中“活动”分区的代码。加载该分区的第一个扇区(引导扇区)。另请注意,分区可能会拆分为更多分区;这意味着硬盘驱动器的所有引导扇区都应该有一个偏移量为0x01BE的分区表(而不仅仅是MBR)。当然,因为BIOS不知道分区,所以在技术上可以使用未分区的硬盘。