Eagterrian Knight
Eagterrian Knight

Reputation: 336

NASM, how to write straight to the hard disk and read from it in Real Mode

On the latest version of Ubuntu, x64.

I am essentially wondering how operating systems are able to install themselves on computers when booted from flash drives, but I would like to do this in Real Mode and not Protected or Long Mode. Surely older operating systems like MS-DOS used to do this.

For Real Mode, is there an interrupt for this? Or do I need to switch to Protected or Long Mode first before I am able to write data straight to the hard disk and/or read from that same area?

Doing this for a small Real Mode OS that has a 2-stage bootloader:

org 0x7C00
mov ah, 0
int 13h
mov dx, 0
mov ah, 2
mov al, 10h
mov dl, 0x80
mov ch, 0
mov dh, 0
mov cl, 2
mov bx, stage2
int 0x13
jmp stage2
times 510-($-$$) db 0
dw 0xAA55

msg db "!!"

%include "read.s" ;read.s does not exist yet, as I do not know how to read from an address on the hard disk
%include "write.s" ;write.s does not exist yet, as I do not know how to write to an address on the hard disk

stage2:
    call ReadStr ;always reads from the same address, if the message is there, sets bl to 0x01. Otherwise, sets bl to 0x00.
    cmp bl, 0x00
    je load
    mov ah, 0eh
    mov al, "#" ;tiny message to tell me that the string is already at the address
    mov bx, 0
    int 10h
    jmp $
load:
    mov ax, [msg]
    call LoadStr ;loads the message to the same address that ReadStr reads from
    mov ah, 0eh
    mov al, "$" ;tiny message to tell me that the string does not already exist at the address
    mov bx, 0
    int 10h
    jmp $

The idea here is that the first time I boot the bootloader, it should print '$', but the second time I boot it, it should print '#' as the data already exists on the hard disk at the specific address. But I don't know how to implement read.s and write.s. Ideally (the main objective of this), the OS will install itself on the computer the first time I boot up the bootloader on a flash drive. Do I need to first set Long Mode to do this, or is it possible in BIOS?

Upvotes: 2

Views: 3917

Answers (2)

someone
someone

Reputation: 1

your answer is on https://en.wikipedia.org/wiki/INT_13H, you should change dl to number of driver and then operations occur on that driver:

mov dl,[that_driver_number]

notice: when bios want's to run bootloader sets dl to bootloader driver (for example if bootloader on cd driver 1, it sets to E0) also when you didn't change that, your operations occur on your boot program for example this code should copy your bootloader on hard drive

Upvotes: 0

Eagterrian Knight
Eagterrian Knight

Reputation: 336

Got something working; the first time it is booted it will print "!#" but every time after that when it boots up, it will print "##" because the flash drive's second sector has been overwritten by the flash drive's third sector. Only thing this is missing is how to do this with the hard drive instead of the flash drive, but at least I now know how to rewrite the flash drive, and thus can simulate memory storage in some way, even if in an inefficient way. Next step is to find out how to inject a bootable sector into the actual computer's memory so that I can use the raw power of RAM to store and manipulate data.

org 0x7C00
stage1:
    mov ah, 2
    mov cl, 2
    mov bx, stage2
    int 13h

    call stage2

    mov ah, 2
    mov cl, 3
    mov bx, stage2
    int 13h

    mov ah, 3
    mov cl, 2
    mov bx, stage2
    int 13h

    mov ah, 2
    mov cl, 2
    mov bx, stage2
    int 13h

    call stage2

    jmp $

times 510-($-$$) db 0
dw 0xAA55
stage2:
    mov ah, 0eh
    mov al, "!"
    mov bx, 0
    int 10h
    ret
times 1024-($-$$) db 0
stage3:
    mov ah, 0eh
    mov al, "#"
    mov bx, 0
    int 10h
    ret
times 1536-($-$$) db 0

Upvotes: 1

Related Questions