2

I am making an operating system called TriangleOS with a few files like sysldr.sys, kernel.sys, etc. When I run it on VMWare I get this error:

Remove disks or other media. Press any key to restart

I'm compiling on Windows 10. I am using partcopy to create my boot sector. I typed:

partcopy.exe boot.asm 0 200 -f0

This is the content of my file 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

The file Floppy16.inc is a file driver helper. Here is the code:

%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

I compiled the boot sector using this command:

nasm.exe -f bin boot.asm -o boot.bin

The project is really big. I made this so that I don't need GRUB. I noticed that my hex editor is at the end 55. Is it normal to be reverse? In my code there is normal 0xAA55. Why does it output Remove disks or other media? How can I fix this problem? Any suggestions?

Razor
  • 1,778
  • 4
  • 19
  • 36
  • Learn to use a debugger and comment your code, especially if you want others to help. – Jester Jan 08 '16 at 14:51
  • Please provide floppy16.inc so you have a Minimal Complete Verifiable Example. – Michael Petch Jan 08 '16 at 15:36
  • 2
    `partcopy.exe boot.asm 0 200 -f0` . I don't know anything about partcopy but this looks wrong. You are copying the source onto the floppy??! How about `partcopy.exe boot.bin 0 200 -f0`? My guess is the error you are getting means that it can't find any bootable media on your virtual machine and it is asking you to insert something. If you really did copy boot.asm onto the virtual floppy instead of boot.bin then I can see that being the case. – Michael Petch Jan 08 '16 at 15:43
  • 2
    Unrelated but still... Don't initialize your stackpointer at an __odd__ address! Better use the __even__ address `mov sp, 0xFFFE` – Fifoernik Jan 08 '16 at 17:34
  • Fifoernik, you didn't seen that i am moving it from system-memory (<1MB) to the 640KB. Because i need that in other parts of my OS. –  Jan 08 '16 at 18:33
  • Please see my updated answer about how you have included `floppy.inc`. You have included it before any code so it will be executed as code, causing weird and wonderful problems. You should move the ` start: jmp main` to just before the include. – Michael Petch Jan 08 '16 at 18:59
  • Oops I meant floppy16.inc – Michael Petch Jan 08 '16 at 19:06
  • Your hex editor doesn't know about the endianness of the data. A word (dw) of 0xaa55 will be placed into the file in reverse. The low byte of the word will appear first and then the high byte. So your hexeditor would be correct showing the byte 0x55 before 0xaa. Seems okay to me. And for the boot signature 0x55 should be before 0xaa, so that part of your file is correct. – Michael Petch Jan 08 '16 at 19:16
  • `dw 0xaa55` is the same as `db 0x55` `db 0xaa` – Michael Petch Jan 08 '16 at 19:22
  • Do you ave a real floppy in your system or are you using some software that makes virtual floppies? – Michael Petch Jan 08 '16 at 19:28
  • i am using the one which make virtual floppies. –  Jan 08 '16 at 19:30
  • But current thing i don't understand that even when i set something to first sector, my notepad++ don't show a change. PartCopy is a crap. Your recommendation for seting something to first sector? –  Jan 08 '16 at 19:31
  • Which program, there are a number of them? Usually you have to mount them do the partcopy and the unmount the image before it can be used by other software like VMWare. Usually failure to unmount will cause things to work improperly. – Michael Petch Jan 08 '16 at 19:31
  • I usually use [DD for Windows](http://www.chrysocome.net//dd) to make disk images. – Michael Petch Jan 08 '16 at 19:33
  • I wrote this answer a few months ago about DD (inlcuding the version for Windows) and creating disk images: http://stackoverflow.com/a/34108769/3857942 . It may be of use. – Michael Petch Jan 08 '16 at 19:35
  • In your case you are probably using a virtual floppy because you have formatted it for DOS and you copy files into the disk as well? I think a key part missing from your question is what virtual floppy software you are using, and whether you properly dismount your virtual floppy after you use partcopy .If you don't dismount the changes you make with partcopy may not be written to the actual virtual floppy file. – Michael Petch Jan 08 '16 at 19:45
  • Any chance you are using [osfmount](http://www.osforensics.com/tools/mount-disk-images.html)? – Michael Petch Jan 08 '16 at 19:50
  • OMFG YOU ARE THE MOST COOLEST GUY ON THE WORLD IM SO EXICTED I HAVE OSSSSS!!!! –  Jan 08 '16 at 21:19
  • 1
    I GIVE YOU ALL THANKS YOU HAVE –  Jan 08 '16 at 21:19
  • Glad you got it going! – Michael Petch Jan 08 '16 at 21:22

1 Answers1

4

Primary Problems

At the top of your code you do this:

bits    16
org     0
%include"Floppy16.inc"

start:  jmp main

The %include"Floppy16.inc" will insert everything in the file floppy16.inc as if it were part of your boot.asm code. The problem is that your Boot Parameter Block (BPB) appears before any code, so the data will literally be executed as code since the bootloader will start executing from physical address 0x07c00. I think you probably should have done this:

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"

By jumping over the BPB data included by the file floppy16.inc you avoid executing the data as code.


At boot, this output:

Remove disks or other media. Press any key to restart

Suggests there may have been a disk inserted in the system but that there was no bootable media found.

What I do find curious is that you seem to generate a binary file from your assembler code but then you use this command:

partcopy.exe boot.asm 0 200 -f0

This will place the assembler source code into the first 512 bytes of the floppy. You want to place the binary file you created onto the floppy. I think you should have used:

partcopy.exe boot.bin 0 200 -f0

File boot.bin is the binary file that was created from this command:

nasm.exe -f bin boot.asm -o boot.bin

Since you copied boot.asm into the boot sector of your floppy the last 2 bytes of the sector would NOT contain the word 0xAA55, and thus wouldn't be detected as a bootable floppy. If there was no other bootable media on your virtual machine you would have got the error about removing media and restarting.


Other Issues

Fifoernik mentioned in the comments:

Unrelated but still... Don't initialize your stackpointer at an odd address! Better use the even address mov sp, 0xFFFE

In the past couple days I wrote a Stackoverflow answer that discussed that issue as well. I'd probably suggest setting SP to 0x0000. A stack that is aligned to an odd word boundary (like 0xffff) will take a significant performance hit if run on real 8086 processors. Setting SP to zero works because it is an even address and the first push of a word onto the stack decrements SP by 2 first and then writes the value. The first word pushed would be at SS:0xfffe .


As it is your code won't run on anything less than a 386 anyway because you have:

mov     fs, ax
mov     gs, ax

fs and gs registers were introduced in the 386 processors. Your code wouldn't run on real 8086/8088/80188/80286 processors. This may be by design, but I felt I should mention it.


Since you are using instructions like lodsb you should consider setting the direction flag. In your case you seem to be relying on forward movement so I'd recommend the us of the CLD instruction near the beginning of the bootloader. You can't be guaranteed it will be set properly.


Your code seems to destroy the contents of DL. The BIOS will pass the boot drive to your bootloader through DL. You might consider saving it so that it can be used to read sectors from the drive that was booted. It is possible you are accounting for this, but it isn't readily apparent without seeing the contents of floppy16.inc

Community
  • 1
  • 1
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 1
    A misaligned stack will cause a performance hit on all x86 CPUs except the latest Intel CPUs (Nehalem or later). Even the later CPUs can suffer from accesses that straddle cache lines, but for typical stack usage it shouldn't be significant. – Ross Ridge Jan 08 '16 at 18:10
  • @RossRidge : What you say is very true. The 8086 specifically takes quite a penalty hit of about 4 clock cycles for access to a misaligned stack which can be quite substantial on those ancient processors, which was why I was more inclined to mention it for that processor. – Michael Petch Jan 08 '16 at 18:16
  • Well, check my update. I am probally blind cause i didn' seen it. But even when i use .bin extension, it's same. **Is this problem from PARTCOPY program? or a VMWARE program? or maybe NASM!?** but when i use Windows's option to copy the image to file, and read it by hex editor, i found the string "Remove disks or other media. Press any key to restart" in the contents. I maybe should use third-party formatter? –  Jan 08 '16 at 18:39
  • @LukaAnđelković Doubtful the issue is a bug in VMWARE, or NASM. With VMWare are you sure you set the floppy drive correctly, and that it is the right size? Partcopy could be a culprit, but I have never used it. It is hard to tell because you don't allow us to see `floppy.inc` so I can't really test it out here.If you modified your question by adding the contents of `floppy.inc` I would be able to test. As it stands though, your floppy is acting as if it isn't being understood by VMWare (probably a configuration error on your part) or the floppy image itself is bad. – Michael Petch Jan 08 '16 at 18:45
  • @LukaAnđelković Yes, I did, that is how I know what is in your floppy16.inc. Now did you read what I said about including it BEFORE the jump? Please see my updated ANSWER. About jumping over the boot parameter block. When the BIOS starts executing your boot sector it is going to execute you boot parameter block as code, which will be nasty. – Michael Petch Jan 08 '16 at 19:12