NASM,如何直接写入硬盘并在实模式下从中读取

时间:2018-05-04 00:10:43

标签: assembly x86 operating-system bootloader hard-drive

在最新版本的Ubuntu上,x64。

我基本上想知道当从闪存驱动器启动时操作系统如何能够在计算机上安装自己,但我想在实模式下执行此操作,而不是保护模式或长模式。当然,像MS-DOS这样的老式操作系统就是这么做的。

对于实模式,是否有中断?或者,在能够将数据直接写入硬盘和/或从同一区域读取之前,是否需要先切换到受保护模式或长模式?

对于具有2阶段引导加载程序的小型Real Mode OS执行此操作:

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 $

这里的想法是,我第一次启动引导程序时,它应该打印' $',但是第二次启动时,它应该打印#'#'因为数据已存在于特定地址的硬盘上。但我不知道如何实现read.s和write.s。理想情况下(主要目标),操作系统将在我第一次在闪存驱动器上启动引导加载程序时自行安装在计算机上。我是否需要先设置长模式才能执行此操作,还是可以在BIOS中使用?

2 个答案:

答案 0 :(得分:1)

有所作为;它第一次启动时会打印“!#”,但每次启动后都会打印“##”,因为闪存驱动器的第二扇区已被闪存驱动器的第三扇区覆盖。唯一缺少的是如何使用硬盘驱动器而不是闪存驱动器,但至少我现在知道如何重写闪存驱动器,因此可以以某种方式模拟内存存储,即使是以低效的方式。下一步是找出如何将可引导扇区注入实际计算机的内存,以便我可以使用RAM的原始功能来存储和操作数据。

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

答案 1 :(得分:0)

您的答案在https://en.wikipedia.org/wiki/INT_13H上,您应将dl更改为驱动程序号,然后对该驱动程序进行操作:

mov dl,[that_driver_number]

注意:当BIOS想要运行bootloader时,将dl设置为bootloader驱动程序(例如,如果cd驱动程序1上的bootloader设置为E0),并且也没有进行更改,则操作将在引导程序上进行 例如,此代码应将您的引导程序复制到硬盘上