Assembly 我的操作系统没有';t在VMWare中启动

Assembly 我的操作系统没有';t在VMWare中启动,assembly,x86,bootloader,osdev,real-mode,Assembly,X86,Bootloader,Osdev,Real Mode,我正在制作一个名为TriangleOS的操作系统,其中包含一些文件,如sysldr.sys,kernel.sys,等等。当我在VMWare上运行它时,我会遇到以下错误: 卸下磁盘或其他介质。按任意键重新启动 我正在Windows 10上编译。我正在使用partcopy创建引导扇区。我键入: partcopy.exe boot.asm 0 200 -f0 这是我的文件boot.asm的内容: bits 16 org 0 %include"Floppy16.inc" start:

我正在制作一个名为TriangleOS的操作系统,其中包含一些文件,如
sysldr.sys
kernel.sys
,等等。当我在VMWare上运行它时,我会遇到以下错误:

卸下磁盘或其他介质。按任意键重新启动

我正在Windows 10上编译。我正在使用
partcopy
创建引导扇区。我键入:

partcopy.exe boot.asm 0 200 -f0
这是我的文件
boot.asm
的内容:

bits    16
org     0
%include"Floppy16.inc"

start:  jmp main
Print:
lodsb       
or  al, al  
jz  PrintDone
mov ah, 0eh 
int 10h
jmp Print   
PrintDone:
ret
main:  
cli                     
mov     ax, 0x07C0      
mov     ds, ax
mov     es, ax
mov     fs, ax
mov     gs, ax
mov     ax, 0x0000      
mov     ss, ax
mov     sp, 0xFFFF
sti                     
mov     si, msgLoading
call    Print
LOAD_ROOT:
xor     cx, cx
xor     dx, dx
mov     ax, 0x0020                        
mul     WORD [bpbRootEntries]             
div     WORD [bpbBytesPerSector]          
xchg    ax, cx
mov     al, BYTE [bpbNumberOfFATs]        
mul     WORD [bpbSectorsPerFAT]           
add     ax, WORD [bpbReservedSectors]     
mov     WORD [datasector], ax             
add     WORD [datasector], cx
mov     bx, 0x0200                        
call    ReadSectors
mov     cx, WORD [bpbRootEntries]         
mov     di, 0x0200                        
.LOOP:
    push    cx
    mov     cx, 0x000B                    
    mov     si, ImageName                 
    push    di
    rep  cmpsb                            
    pop     di
    je      LOAD_FAT
    pop     cx
    add     di, 0x0020                    
    loop    .LOOP
    jmp     FAILURE
LOAD_FAT:
mov     dx, WORD [di + 0x001A]
mov     WORD [cluster], dx                
xor     ax, ax
mov     al, BYTE [bpbNumberOfFATs]        
mul     WORD [bpbSectorsPerFAT]           
mov     cx, ax
mov     ax, WORD [bpbReservedSectors]     
mov     bx, 0x0200                        
call    ReadSectors
mov     ax, 0x0050
mov     es, ax                            
mov     bx, 0x0000                        
push    bx
LOAD_IMAGE:
mov     ax, WORD [cluster]                
pop     bx                                
call    ClusterLBA                        
xor     cx, cx
mov     cl, BYTE [bpbSectorsPerCluster]   
call    ReadSectors
push    bx
mov     ax, WORD [cluster]                
mov     cx, ax                            
mov     dx, ax                            
shr     dx, 0x0001                        
add     cx, dx                            
mov     bx, 0x0200                        
add     bx, cx                            
mov     dx, WORD [bx]                     
test    ax, 0x0001
jnz     .ODD_CLUSTER 
.EVEN_CLUSTER:
    and     dx, 0000111111111111b         
    jmp     .DONE 
.ODD_CLUSTER:
    shr     dx, 0x0004                    
.DONE:
    mov     WORD [cluster], dx            
    cmp     dx, 0x0FF0                    
    jb      LOAD_IMAGE   
DONE:
     mov     si, msgCRLF
     call    Print
     push    WORD 0x0050
     push    WORD 0x0000
     retf
FAILURE:
mov     si, msgFailure
call    Print
mov     ah, 0x00
int     0x16          
int     0x19          
bootdevice  db 0
ImageName:   db "KRNLDR  SYS"
msgLoading:  db 0x0D, 0x0A, "Reading Kernel Loader", 0x00
msgCRLF:     db 0x0D, 0x0A, 0x00
msgProgress: db ".", 0x00
msgFailure:  db 0x0D, 0x0A, "Can't find Kernel Loader (krnldr.sys). Press Any Key to Reboot", 0x0D, 0x0A, 0x00
TIMES 510-($-$$) DB 0
DW 0xAA55
文件
Floppy16.inc
是一个文件驱动程序助手。代码如下:

%ifndef __FLOPPY16_INC_
%define __FLOPPY16_INC_
bits    16
bpbOEM          db "TriangOS"
bpbBytesPerSector:      DW 512
bpbSectorsPerCluster:   DB 1
bpbReservedSectors:     DW 1
bpbNumberOfFATs:    DB 2
bpbRootEntries:     DW 224
bpbTotalSectors:    DW 2880
bpbMedia:       DB 0xf0
bpbSectorsPerFAT:   DW 9
bpbSectorsPerTrack:     DW 18
bpbHeadsPerCylinder:    DW 2
bpbHiddenSectors:   DD 0
bpbTotalSectorsBig:     DD 0
bsDriveNumber:          DB 0
bsUnused:       DB 0
bsExtBootSignature:     DB 0x29
bsSerialNumber:         DD 0xa0a1a2a3
bsVolumeLabel:          DB "TOS FLOPPY "
bsFileSystem:           DB "FAT12   "
datasector  dw 0x0000
cluster     dw 0x0000
absoluteSector db 0x00
absoluteHead   db 0x00
absoluteTrack  db 0x00
ClusterLBA:
    sub     ax, 0x0002
    xor     cx, cx
    mov     cl, BYTE [bpbSectorsPerCluster]
    mul     cx
    add     ax, WORD [datasector]
    ret
LBACHS:
    xor     dx, dx                    
    div     WORD [bpbSectorsPerTrack] 
    inc     dl                        
    mov     BYTE [absoluteSector], dl
    xor     dx, dx                    
    div     WORD [bpbHeadsPerCylinder]
    mov     BYTE [absoluteHead], dl
    mov     BYTE [absoluteTrack], al
    ret
; CX=>Kolko sektori da procita
; AX=>Pocetni sektor
; ES:EBX=>Na koju mem. lokaciju da ga stavi
ReadSectors:
     .MAIN
          mov     di, 0x0005                  
     .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 [bsDriveNumber]
          int     0x13                        
          jnc     .SUCCESS                    
          xor     ax, ax                      
          int     0x13                        
          dec     di                          
          pop     cx
          pop     bx
          pop     ax
          jnz     .SECTORLOOP                 
          int     0x18
     .SUCCESS
          pop     cx
          pop     bx
          pop     ax
          add     bx, WORD [bpbBytesPerSector]
          inc     ax                          
          loop    .MAIN                       
          ret

%endif
我使用以下命令编译引导扇区:

nasm.exe -f bin boot.asm -o boot.bin
partcopy.exe boot.asm 0 200 -f0
nasm.exe -f bin boot.asm -o boot.bin
这个项目真的很大。我做这个是为了不需要食物。我注意到我的十六进制编辑器在
55
的末尾。反转正常吗?在我的代码中有正常的
0xAA55
。为什么会输出
删除磁盘或其他介质?
如何解决此问题?有什么建议吗?

主要问题 在代码的顶部,您可以执行以下操作:

bits    16
org     0
%include"Floppy16.inc"

start:  jmp main
%include“Floppy16.inc”
将插入文件
Floppy16.inc
中的所有内容,就像它是您的
boot.asm
代码的一部分一样。问题是,您的引导参数块(BPB)出现在任何代码之前,因此数据将作为代码执行,因为引导加载程序将从物理地址0x07c00开始执行。我想你应该这样做:

bits    16
org     0
start:  jmp main
nop               ; Place NOP so BPB starts at the 4th byte of binary file. 
                  ; relative(short) JMP is 2 bytes long. NOP acts as 1 byte padding.

%include"Floppy16.inc"
通过跳过文件
floppy16.inc
中包含的BPB数据,可以避免将数据作为代码执行


启动时,此输出:

卸下磁盘或其他介质。按任意键重新启动

表明系统中可能插入了磁盘,但未找到可引导介质

我确实感到奇怪的是,您似乎从汇编代码生成了一个二进制文件,但随后您使用以下命令:

nasm.exe -f bin boot.asm -o boot.bin
partcopy.exe boot.asm 0 200 -f0
nasm.exe -f bin boot.asm -o boot.bin
这将把汇编程序源代码放入软盘的前512字节。您想将创建的二进制文件放在软盘上。我认为你应该使用:

partcopy.exe boot.bin 0 200 -f0
File
boot.bin
是通过以下命令创建的二进制文件:

nasm.exe -f bin boot.asm -o boot.bin
partcopy.exe boot.asm 0 200 -f0
nasm.exe -f bin boot.asm -o boot.bin
由于您将
boot.asm
复制到软盘的引导扇区中,扇区的最后2个字节将不包含单词0xAA55,因此不会被检测为可引导软盘。如果您的虚拟机上没有其他可引导介质,则会出现删除介质并重新启动的错误


其他问题 评论中提到的Fifoernik:


不相关但仍然。。。不要在奇数地址初始化堆栈指针!最好使用偶数地址mov sp,0xFFFE

在过去的几天里,我写了一篇文章,也讨论了这个问题。我可能会建议将SP设置为0x0000。如果在实际8086处理器上运行,与奇数字边界对齐的堆栈(如0xffff)将受到显著的性能影响。将SP设置为零是有效的,因为它是一个偶数地址,第一次将一个字推送到堆栈上会先将SP减2,然后写入该值。推送的第一个单词是SS:0xfffe


因此,您的代码无论如何都不会在386以下的机器上运行,因为您有:

mov     fs, ax
mov     gs, ax
在386处理器中引入了
fs
gs
寄存器。您的代码不会在真正的8086/8088/80188/80286处理器上运行。这可能是故意的,但我觉得我应该提一下


因为您使用的指令如<代码> LoSb您应该考虑设置方向标志。在您的情况下,您似乎依赖于向前移动,因此我建议在引导加载程序的开头附近使用

CLD
指令。你不能保证它会被正确设置



您的代码似乎破坏了DL的内容。BIOS将通过DL将引导驱动器传递给引导加载程序。您可以考虑保存它,以便它可以从启动的驱动器读取扇区。您可能对此进行了解释,但如果没有看到
floppy16.inc

的内容,就很难看出这一点。学习使用调试器并注释您的代码,特别是如果您希望他人帮助的话。请提供floppy16.inc,这样您就有了一个最小的完整可验证示例。
partcopy.exe boot.asm 0 200-f0
。我对partcopy一无所知,但这看起来不对。您正在将源文件复制到软盘上??!如何
partcopy.exe boot.bin 0 200-f0
?我的猜测是,您得到的错误意味着它在您的虚拟机上找不到任何可引导媒体,它要求您插入一些内容。如果您真的将boot.asm复制到虚拟软盘上而不是boot.bin,那么我可以看到情况是这样的。不相关但仍然。。。不要在奇数地址初始化堆栈指针!最好使用偶数地址
mov sp,0xFFFE
谢谢大家,堆栈未对齐将导致除最新Intel CPU(Nehalem或更高版本)之外的所有x86 CPU的性能下降。即使是较新的CPU也会受到跨越缓存线的访问的影响,但对于典型的堆栈使用来说,这并不重要。@RossRidge:你说的非常正确。8086特别需要4个时钟周期才能访问未对齐的堆栈,这在那些古老的处理器上非常重要,这就是为什么我更倾向于提到它的原因。好吧,检查我的更新。我可能是瞎的,因为我没看见。但即使我使用.bin扩展名,它也是一样的。这是PARTCOPY程序的问题吗?还是VMWARE计划?或者NASM!?但当我使用Windows的选项将图像复制到文件中,并通过hex editor读取它时,我在内容中发现字符串“移除磁盘或其他媒体。按任意键重新启动”。我也许应该使用第三方格式化程序?@LukaAnđelković怀疑问题是否是VMWARE或NASM中的缺陷。使用VMWare,您确定软盘驱动器设置正确,大小正确吗?Partcopy可能是罪魁祸首,但我从未使用过它。很难说b