Вопрос

Background Information

I am developing a simple DOS like OS. So I am not planning to enter in Protected Mode anytime soon. The OS will be written in assembly; NASM syntax by the way. The boot sector is supposed to save the boot sector on the first sector of the hard disk, and the OS' code on the second sector. So that it can boot from the hard disk, and not from the CD image.

The Issue

The problem is that boot sector seems to save everything properly on the hard disk. But when I restart the VMware Player, and eject the virtual CD-ROM. It boots a background green color (Figure 1.1). Which can only mean that boot sector isn't loading the second sector at address 0x7e00, and fails to jump. The weird thing is the carry flag is not being set, so I am assuming no error has occurred. So basically when I boot from the CD-ROM image, it shows everything fine as in (Figure 1.2). But when I restart and boot from the hard disk it fails to jump to the OS which should have been loaded at 0x7e00. The boot sector is loaded at 0x7c00. I am assuming my segment address is correct, maybe my offset address is incorrect, or maybe my disk writing and reading is totally wrong?

Things That The OS Has Successfully Accomplished

  • Basic system calls in the form of software interrupts. Modified the IVT (Interrupt Vector Table)

  • Load boot sector on the primary hard disk, and the BIOS can load the boot sector from the hard disk into memory location 0x7c00

The Code That Might Be Causing The Issue

Here is the boot.asm code:

[ORG 0x7c00] ; BIOS loads at 0x7c00 in memory

jmp start

%include "C:\Users\OSDEV\OS-SRC\MonsterOS\source\syscalls\syscalls.inc"

start:

xor ax, ax ; make it zero
mov ds, ax ; Data segment is zero

;Set desired video mode (Graphics Mode)
mov ah, 0
mov al, 12h
int 10h

call init_int

;Set desired background color (Green)
mov ah, 0x0b 
mov bh, 0
mov bl, 2
int 10h 

; Display Box Shaped Cursor

mov ch, 0
mov cl, 7
mov ah, 1
int 10h


;Save BootLoader on the DISK


xor ax, ax
mov es, ax    ; ES <- 0
mov cx, 1    ; cylinder 0, sector 1
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7c00h ; segment offset of the buffer
mov ax, 0301h ; AH = 03 (disk write), AL = 01 (number of sectors to write)
int 13h

;Save OS on the DISK


xor ax, ax
mov es, ax    ; ES <- 0
mov cx, 2     ; cylinder 0, sector 2
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7e00h ; segment offset of the buffer
mov ax, 0301h ; AH = 03 (disk write), AL = 01 (number of sectors to write)
int 13h

;Load OS from DISK at 0x7e00

xor ax, ax
mov es, ax    ; ES <- 0
mov cx, 2     ; cylinder 0, sector 2
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk)
mov bx, 7e00h ; segment offset of the buffer
mov ax, 0201h ; AH = 02 (disk read), AL = 01 (number of sectors to read)
int 13h
jc err


jmp 0h:0x7e00 ; Jump To OS

err:

mov ax, err_msg
mov bh, 0
mov bl, 0xf
int 21h ; Print error message

err_msg: db 'Error Failed To Load OS From Disk!', 0

times 510-($-$$) db 0
   db 0x55
   db 0xAA

Here is the os.asm:

[ORG 0x7e00]



xor ax, ax ; make it zero
mov ds, ax ; Data segment is zero
mov es, ax



; Clear Screen

int 27h

;Set desired background color (Green)
mov ah, 0x0b 
mov bh, 0
mov bl, 2
int 0x10    

; Display Box Shaped Cursor

mov cx, 0607h 
mov ah, 1
int 10h

; Print Desired Message

mov ax, msg
mov bh, 0
mov bl, 0xf
int 21h


int 23h ; Print newline



hang:

    mov ax, buffer
    int 25h ; SIZE(buffer)

    mov ax, buffer
    int 24h ;ZERO(buffer)

    ; Print Desired Message

    mov ax, cli_msg
    mov bh, 0
    mov bl, 0xf

    int 21h ; print ax=msg bl=blue

    ; Get Input
    mov bx, buffer
    int 22h ; Read From Keyboard And Print The String With Line Feed

    ; ECHO String Stored At The Address Buffer

    mov ax, buffer
    mov bh, 0
    mov bl, 0xf
    int 21h ; 

    int 23h ; Print newline

    jmp hang

msg: db 'Welcome To MonsterOS!', 0
cli_msg: db 'MonsterOS> ', 0
buffer: times 64 db 0

Here is the script build.bat code:

nasm -f bin C:\Users\OSDEV\OS-SRC\MonsterOS\source\boot.asm -o C:\Users\OSDEV\OS-SRC\MonsterOS\bin\boot.bin 
nasm -f bin C:\Users\OSDEV\OS-SRC\MonsterOS\source\os.asm -o C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.bin 
copy /b C:\Users\OSDEV\OS-SRC\MonsterOS\bin\boot.bin + C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.bin C:\Users\OSDEV\OS-SRC\MonsterOS\bin\img.bin
miso C:\Users\OSDEV\OS-SRC\MonsterOS\bin\os.iso -ab C:\Users\OSDEV\OS-SRC\MonsterOS\bin\img.bin

Post Script

The interrupt 21h, 22h, 23h,24h,25h,26h, are custom software interrupts that I wrote for my OS. If you have any more question or need more code or info, I am here to provide more information.

The Solution

For those who care, I solved it by writing img.bin in a VHD created by VirtualBox and booted from the VHD. So it works like a charm. I used a Hex Editor by the way.

Figure 1.1 Figure 1.1

Figure 1.2 Figure 1.2

Это было полезно?

Решение

Okay, you're excused. Nobody was born knowing this stuff!

Going back to when it worked (your figure 1.2), you "must have" read sector 2 from your CD image to 0x7E00 - similar to what you do at the end of your bootsector, only from a different drive (dl). I'm guessing that BIOS thinks the CD image is drive 0. The boot drive number should be in dl, so you might be able to just leave it alone (make dh 0, though). After doing this, you can probably write from 0x7C00 to hard drive (drive 80h) sector 1 and from 0x7E00 to drive 80h sector 2 - as you're doing. But do you really want to do this every time you boot?

What I would do, after copying boot.bin and os.bin to img.bin, is to write img.bin to hard drive using... John Fine's partcopy if you can find that, or rawwrite, or a port of dd (a Unix utility). Or you can do it with DEBUG. Or it isn't hard to write yourself a little program to do it. Then you should be able to boot from the hard drive, skipping the iso and the CD image entirely.

BIOS loads sector 1 to 0x7C00, but after that it's up to your boot code to load sector 2 to 0x7E00 and jump to it... or write it to hard drive, read it back and jump to it, but it seems pointless to do this on every boot.

As your OS grows, it'll take up more than one sector, so you'll need to read more than one sector. If your code is working, but crashes when you add one more function, this is probably what's happening. Easily fixed - just keep an eye on the size of os.bin, and read more sectors if/when it exceeds 512 bytes.

Minor nit: if your error message gets printed, you'll then "fall through" to trying to execute the message and on to "into the woods". Put a hang: jmp hang after printing to catch it. You're not getting an error (carry flag) because your code is happily writing 0x7E00 to disk and reading it back, even though there's no "code" there. I think that's what's happening...

One thing to watch out for: Bios always thinks the hard drive it booted from is "drive 80h". If you boot from some other drive, the drive you want to write your bootsector and OS to may be drive 81h or 82h or ???. Be careful!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top