我已经为一个小型操作系统编写了一段时间,我一直使用VM测试它,特别是它在QEMU、VMWare和VirtualBox上工作。内核希望从HDD引导,所以为了在真正的硬件上测试它,我将它烧到一个真正的硬盘上,并将它连接到一个真正的pc上。从此就成了一场灾难!一切都在起作用。我已经部分修复了我可以找到的所有错误,但我真的不知道是什么原因造成的: VBR在被MBR加载之后,只能加载第二阶段引导加载器的一部分;在BOCHS中,它只加载第一个集群,但是在真正的pc中,内存中加载的代码更少。所有处理FAT16的代码都在一个文件中,但是它仍然太大,不能在这里发布,所以我将在GitHub上提供它的链接。此文件(/boot/include/fat16.inc)由主VBR文件(/boot/src/vbr.asm)包含。一些初始化在vbr.asm中可能会丢失,但由于空间限制,它们在MBR文件(/boot/src/mbr.asm)中被处理。
编辑
如果出于某些原因,GitHub回购丢失了,我将为未来的读者张贴for 16.inc的代码:
%ifndef __FAT12_INC__
%define __FAT12_INC__
; this file relies on a word variable called partition_offset
; partition_offset should contain the address in memory of
; the current partition entry in the table
bits 16
%define ROOT_OFFSET Mem.Loader.FAT16.Data
%define ROOT_SEG LIN_TO_FAR_ADDR(ROOT_OFFSET)
%define FAT_OFFSET Mem.Loader.FAT16.Data
%define FAT_SEG LIN_TO_FAR_ADDR(FAT_OFFSET)
%include "include/disk.inc"
;*********************************;
; Sets Rot Directory informations ;
; Returns: ;
; ecx => location in sectors. ;
; eax => size in sectors ;
;*********************************;
GetRootInfo:
; clear registers
xor eax, eax
xor ecx, ecx
; compute location of root directory in sectors and store in "ecx"
mov al, byte [bpb_NumberOfFATs] ; number of FATs
mul word [bpb_SectorsPerFAT] ; sectors used by FATs
add ax, word [bpb_ReservedSectors] ; reserved sectors
mov cx, ax ; move into cx
mov ax, word [partition_offset]
add cx, word [eax + 8] ; offset from partition information
; compute size of root directory in sectors and store in "ax"
mov ax, 32 ; 32 byte directory entry
mul word [bpb_RootEntries] ; total size of directory
div word [bpb_BytesPerSector] ; sectors used by directory
ret
;***************************************;
; Load Root Directory Table to ROOT_SEG ;
;***************************************;
LoadRoot:
call GetRootInfo
; read Root into memory at ROOT_SEG
mov dl, byte [bpb_DriveNumber]
mov ebx, dword ROOT_SEG
call ReadSectorsLBA
ret
;****************************;
; Loads FAT table to FAT_SEG ;
;****************************;
LoadFAT:
pushad
; clear registers
xor ax, ax
xor cx, cx
; compute size of FAT and store in "ax"
mov ax, word [bpb_SectorsPerFAT] ; number of FATs
; compute location of FAT and store in "ecx"
mov cx, word [partition_offset]
mov cx, word [ecx + 8] ; offset from partition information
add cx, word [bpb_ReservedSectors]
; read FAT into memory at FAT_SEG
mov dl, byte [bpb_DriveNumber]
mov ebx, dword FAT_SEG
call ReadSectorsLBA
popad
ret
;***********************************************;
; Search for filename in root table ;
; Parameters: ;
; si => File name ;
; Returns: ;
; ax => File index number in directory table. ;
; di => Location of the file root entry ;
;***********************************************;
FindFile:
; store registers
push cx
push bx
push es
mov bx, si ; save filename for later
push ROOT_SEG >> 16 ; locate first root entry
pop es
mov di, ROOT_SEG ; ES:DI is memory location of root dir
mov cx, word [bpb_RootEntries] ; load loop counter
; browse root directory for binary image
cld ; clear direction flag
.loop:
push cx
mov cx, 11 ; eleven character name. Image name is in SI
mov si, bx ; image name is in BX
push di
rep cmpsb ; test for entry match [ DS:SI - ES:DI ]
pop di
je .Found
pop cx
add di, 32 ; queue next directory entry
loop .loop
.NotFound:
; set error code
mov ax, -1
; restore registers and return
pop es
pop bx
pop cx
ret
.Found:
; return value into AX contains entry of file
pop ax
; restore registers and return
pop es
pop bx
pop cx
ret
;**********************************************;
; Gain information about the file to be loaded ;
; Parameters: ;
; edi => Location of the file root entry ;
;**********************************************;
PrepareFile:
; get starting cluster
push word ROOT_SEG >> 16
pop es
mov ax, word [es:edi + 0x1A] ; retrive cluster from root entry
mov word [cluster], ax
; get 0th cluster address
call GetRootInfo
add eax, ecx
mov dword [first_cluster_sector], eax
call LoadFAT
ret
;*********************************************;
; Read the current selected cluster in memory ;
; Parameters: ;
; ebx => Buffer to load file to ;
;*********************************************;
LoadNextCluster:
; zero out registers for calculations
xor cx, cx
xor dx, dx
; convert the cluster in lba
mov ax, word [cluster]
sub ax, 2
mov dl, byte [bpb_SectorsPerCluster]
mul dx
xchg cx, ax
add ecx, dword [first_cluster_sector]
; sets the others parameters and read the disk
mov dl, byte [bpb_DriveNumber]
mov al, byte [bpb_SectorsPerCluster]
call ReadSectorsLBA
; get next cluster from fat table
xor eax, eax
mov ax, word [cluster]
mov dx, 2
mul dx ; since fat table is an array of words (2 byte)
push word FAT_SEG >> 16
pop es
mov dx, word [dword es:eax]
mov word [cluster], dx
ret
;*******************************************************;
; Check if the current reading file has been compleated ;
; Returns: ;
; cf => set on compleated ;
;*******************************************************;
FileReadCompleated:
; test if it was the last cluster
cmp word [cluster], 0xFFFF
je .complete
cmp word [cluster], 0xFFF8
je .complete
.incomplete:
clc ; clear carry flag
ret
.complete:
stc ; set carry flag
ret
;************************************;
; Load file ;
; Parameters: ;
; es:si => File name ;
; ebx => Buffer to load file to ;
; Returns: ;
; ax => -1 on error, 0 on success ;
;************************************;
LoadFile:
.findFile:
; find file using name in es:si
call FindFile
cmp ax, -1
je .done ; file not found
.loadFilePre:
call PrepareFile
.nextCluster:
call LoadNextCluster
call FileReadCompleated
jc .success
; increase address
xor eax, eax
mov ax, word [bpb_SectorsPerCluster]
mul word [bpb_BytesPerSector]
mov ecx, eax
shr eax, 4
shl eax, 16
and ecx, 0xF
or eax, ecx
add ebx, eax
; check if riporto
mov eax, ebx
and eax, (1 << 4)
cmp eax, 0
je .nextCluster
; fix riporto
xor ebx, 1 << 4
add ebx, 1 << 16
jmp .nextCluster
.success:
xor ax, ax
.done
ret
cluster dw 0x0000
first_cluster_sector dd 0x00000000
%endif ; __FAT12_INC__发布于 2021-04-01 08:06:11
这并不是我所拥有的问题的完全解决方案,但我还是想把它作为一个答案来发布,因为它对未来的读者是有用的。
事实上,在我的例子中,int 13.42破坏了ebx的内容。
现在我可以在BOCHS和Microsoft中启动我的映像,它仍然不能在真正的硬件上启动,但这肯定是一件重要的事情。
https://stackoverflow.com/questions/66866840
复制相似问题