4

So I thought I'd try to make a DOS copy but it runs on a floppy and its just a simple plug and play with fat12 partition for user applications and drivers.

I first attempted to load my kernel using int 13,2h at 0x0000:0x7000 but it seemed that it would cause CF to be set but a "no error" code provided in AH. I spent a good 30 minutes debugging before I just tried another address (which was 0x0000:0x0600 in my case) and I was stunned that it actually fixed the problem.

But now I am confused, I thought 0x0000:0x7000 and above and below were safe to use or safe majority of the times.

Oh and I am using qemu-system-i386. Kernel is 11 bytes (Testing currently)

[bits 16]
org 0x7C00

; macros
%include "../include/misc.inc"

jmp 0x0000:start

; notice: perserve the boot drive in dl so the kernel can save it

start:
    cli

    xor ax, ax ; cs
    mov ds, ax
    mov es, ax

    mov ss, ax
    mov sp, 0x8000

    sti

    ; set video mode
    mov al, 0x13
    int 0x10

    ; load kernel into 0x0000:0x7000 from floppy 
    mov bx, 0x7000
    mov ah, 0x02
    
        mov al, 1
        xor ch, ch ; 0
        mov cl, 2
        xor dh, dh ; 0
        ; drive number (DL)

    int 0x13

    jc disk_error

    jmp 0x0000:0x7000

disk_error: ; error handling for int 13,2h failure

    xor ah, ah
    mov al, 0x03
    int 0x10

    mov ah, 0x0E
    mov si, disk_error_message

    mov cl, 17
    .log_error:
        mov al, [si]
        int 0x10
        inc si

    loop cl, .log_error

    hlt

; Variables

disk_error_message: db "Disk read failure"

times 510 - ($ - $$) db 0
db 0x55, 0xAA ; boot signature

How I am building the floppy (Simple and effective)

make -C src/boot/
make[1]: Entering directory '/home/mekebabman/Desktop/Simple16/src/boot'
nasm -f bin mbr.nasm -o ../../build/mbr.bin
make[1]: Leaving directory '/home/mekebabman/Desktop/Simple16/src/boot'
dd if=/dev/zero of=build/img/S16-0.0-floppy.img bs=512 count=2880 conv=notrunc
2880+0 records in
2880+0 records out
1474560 bytes (1.5 MB, 1.4 MiB) copied, 0.0301179 s, 49.0 MB/s
dd if=build/mbr.bin of=build/img/S16-0.0-floppy.img bs=512 seek=0 count=1 conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 0.000161682 s, 3.2 MB/s
dd if=build/kernel/main.bin of=build/img/S16-0.0-floppy.img bs=512 seek=1 conv=notrunc
0+1 records in
0+1 records out
11 bytes copied, 0.00014582 s, 75.4 kB/s

In case you want to see the command I am using for qemu

qemu-system-i386 -drive file=$<,format=raw,if=floppy -boot order=a

and the test kernel

[bits 16]
org 0x7000

; macros
%include "../include/misc.inc"

kstart:
    cli

    ; Segments are already 0x0000
    ; xor ax, ax
    ; mov ds, ax
    ; mov es, ax

    ; mov sp, ax
    mov sp, 0x7400 ; 1kib stack (IGNORE THIS! RANDOM POSITION I PICKED)

    mov byte [boot_drive], dl

    sti

    hlt

; variables

boot_drive: db 0

oh and the "loop" macro is just

dec <reg>
jnz <address>

OH BTW! When I manually set the boot drive in DL, I was able to use 0x0000:0x7000 but that is also another weird thing.

9
  • Please show all the commands for how you build your boot sector and kernel, how you construct the disk image, and how you execute qemu. There could be something wrong with one of those steps. Commented Sep 5 at 17:14
  • 1
    If qemu were really using that address, it would be a serious and rather absurd bug. It's an emulator; it should have no need to keep its own stuff in the vm's memory. That sounds more like the AI bullshitting you than actual sense. Anyway, we can't jump to the conclusion of an emulator bug until we've conclusively ruled out all possible bugs in your code. Commented Sep 5 at 17:31
  • 2
    hlt with interrupts enabled will only stop your code until the arrival of the next interrupt, such as the timer interrupt every 55ms. After that it'll continue executing whatever bytes are next in memory. Conceivably it could get back to executing your boot sector code a second time. Try taking out the sti and see if anything changes. Commented Sep 5 at 17:53
  • 1
    I took out the sti and it works now??? What the hell Commented Sep 5 at 18:00
  • 2
    Combination of Nate's last comment explanation and question's last paragraph (BTW DL thing) is that ties it together. The boot loader resets everything used by int13h BUT dl (which is supposed to come from the BIOS). So loader loads the kernel, executes it, the kernel executes to the end, fails to halt and slips through to the bootloader AGAIN, but this time dl register contains some garbage so second execution of read-disk fails. IOW it always worked, your kernel always loaded and executed regardless of the address. You just failed to see that because it doesn't do anything. Commented Sep 5 at 18:10

1 Answer 1

5

Basically I didn't know that hlt would continue after a interrupt, causing my hang to not work.

I loaded my kernel (which is a test kernel currently) at 0x0000:0x7000 which is actually perfectly fine but I used hlt to hang, not knowing that hlt wouldn't actually hang and so the CPU would basically go all the way down to 0x0000:0x7C00 (the bytes were 0x00 for some reason) and something would go wrong in the boot record (unsure what exactly) which caused the jump to disk_error.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.