如何修复尝试读取扇区时的磁盘读取错误

问题描述 投票:0回答:1

我正在按照这个教程构建一个简单的操作系统。我的问题是它调用磁盘加载函数,当我启动它时,它给我一个磁盘读取错误。这是我的 boot_sect.asm 代码:

[org 0x7c00]
KERNEL_OFFSET equ 0x1000

    mov [BOOT_DRIVE], dl

    mov bp, 0x9000
    mov sp, bp


    mov bx, MSG_REAL_MODE
    call print_string

    call load_kernel
    mov bx, MSG_LOAD_KERNEL
    call print_string
    call switch_to_pm

    jmp $

%include "print_string.asm"
%include "disk_load.asm"
%include "gdt.asm"
%include "print_string_pm.asm"
%include "switch_to_pm.asm"

[bits 16]

load_kernel:

    mov bx, MSG_LOAD_KERNEL
    call print_string

    mov bx, KERNEL_OFFSET
    mov dh, 15
    mov dl, [BOOT_DRIVE]

    call disk_load 

    ret

[bits 32]
BEGIN_PM:

    mov ebx, MSG_PROT_MODE
    call print_string_pm

    call KERNEL_OFFSET

    jmp $


BOOT_DRIVE db 0
MSG_REAL_MODE db "Started in 16-bit Real Mode", 0
MSG_PROT_MODE db "Successfully landed in 32-bit Protected Mode", 0
MSG_LOAD_KERNEL db "Loading kernel into memory", 0

; Padding
times 510-($-$$) db 0
dw 0xaa55

和我的disk_load.asm:

; load DH sectors to ES:BX from drive DL
disk_load :

    push dx ; Store DX on stack so later we can recall
    ; how many sectors were request to be read ,
    ; even if it is altered in the meantime

    mov ah, 0x02 ; BIOS read sector function
    mov al, dh ; Read DH sectors
    mov ch, 0x00 ; Select cylinder 0
    mov dh, 0x00 ; Select head 0
    mov cl, 0x02 ; Start reading from second sector ( i.e.
    ; after the boot sector )

    int 0x13; BIOS interrupt
    jc disk_error ; Jump if error ( i.e. carry flag set )
    pop dx ; Restore DX from the stack
    cmp dh, al ; if AL ( sectors read ) != DH ( sectors expected )
    jne disk_error2 ; display error message
    ret

disk_error :
    mov bx , DISK_ERROR_MSG
    call print_string
    jmp $
disk_error2 :
    mov bx , DISK_ERROR_MSG2
    call print_string
    jmp $

; Variables
DISK_ERROR_MSG db " Disk read error 1 !" , 0
DISK_ERROR_MSG2 db " Disk read error 2 !" , 0

这篇文章说我可能需要

es
为零,但是当我把

xor bx, bx
mov es, bx

int 0x13
之上,它只是在中断时挂起。我该如何解决这个问题?

编辑

在这个例子中,我让它在中断后显示

hello
,但是,除非我删除
xor bx, bx mov es, bx
,否则它不会显示它,所以这就是为什么我认为它卡在那里:

; load DH sectors to ES:BX from drive DL
disk_load :

    push dx ; Store DX on stack so later we can recall
    ; how many sectors were request to be read ,
    ; even if it is altered in the meantime

    mov ah, 0x02 ; BIOS read sector function
    mov al, dh ; Read DH sectors
    mov ch, 0x00 ; Select cylinder 0
    mov dh, 0x00 ; Select head 0
    mov cl, 0x02 ; Start reading from second sector ( i.e.
    ; after the boot sector )

    xor bx, bx
    mov es, bx

    int 0x13; BIOS interrupt

    mov bx, message         ;  This should print `hello` after the interrrupt
    call print_string       ;

    jc disk_error ; Jump if error ( i.e. carry flag set )
    pop dx ; Restore DX from the stack
    cmp dh, al ; if AL ( sectors read ) != DH ( sectors expected )
    jne disk_error2 ; display error message
    ret

    . . .
assembly nasm x86-16 osdev bios
1个回答
0
投票

当我启动它时,它给我一个磁盘读取错误。

每当返回时设置进位标志时,向我们展示 BIOS 在 AH 寄存器中返回的实际 状态字节 将是最有用的!


请阅读将扇区加载到内存时出现磁盘读取错误以获取解释和工作代码。

[org 0x7c00]
KERNEL_OFFSET equ 0x1000

    mov [BOOT_DRIVE], dl

    mov bp, 0x9000
    mov sp, bp

当 BIOS 将引导加载程序放入内存时,您唯一可以确定的寄存器是 DL,它保存着 driveID。由于段寄存器在实模式编程中非常重要,因此您必须正确设置它们。根据您的

[org 0x7c00]
,接下来是您必须写的:

[org 0x7C00]
KERNEL_OFFSET equ 0x1000

  xor  ax, ax
  mov  ds, ax
  mov  es, ax
  mov  ss, ax            ; Keep these two together and
  mov  sp, 0x9000        ;  very importantly in this order
  mov  [BOOT_DRIVE], dl

我建议您将当前的 disk_load 过程替换为我提供链接的答案中的过程。确保正确调用它。


int 0x13; BIOS interrupt

mov bx, message         ;  This should print `hello` after the interrrupt
call print_string       ;

jc disk_error ; Jump if error ( i.e. carry flag set )

在屏幕上显示临时消息是一种很好的调试技术,但不要忘记print_string过程将破坏从BIOS.ReadSectors函数02h获得的进位标志。
要成功检查进位标志,请使用

pushf
popf
,如下所示:

  mov  ah, 02h     ; BIOS.ReadSectors
  int  0x13
  pushf
  mov  bx, message
  call print_string
  popf
  jc   disk_error  ; Jump if error ( i.e. carry flag set )

这将保留堆栈上的进位标志。如果您不能确定 print_string 已保留 AX,则以相同的方式在此处保留 AX...

© www.soinside.com 2019 - 2024. All rights reserved.