如何修复:"Disk Read Error" 在我的引导加载程序中
How to fix: "Disk Read Error" in my bootloader
我正在为 linux 使用 Windows 10 和 Windows 子系统。
我已经开始用 Assembly 和 C 创建自己的操作系统。
我正在学习教程。
我遇到了 2 个问题。
错误一:
当我 Link 并创建 bin 文件时,我收到警告:
"ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000"
这重要吗?
错误2:
编译我的代码后,没有错误。但是当我启动我的操作系统时,它显示错误:磁盘读取错误!
请帮助我。
Boot.asm
[org 0x7c00]
KERNEL_OFFSET equ 0x1000
mov [BOOT_DRIVE], dl
mov bp, 0x9000
mov sp, bp
mov si, MSG_REAL_MODE
call print
call load_kernel
call switch_to_pm
jmp $
%include "printstr.asm"
%include "diskload.asm"
[bits 16]
load_kernel :
mov si, MSG_LOAD_KERNEL
call print
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
times 510 -( $ - $$ ) db 0
dw 0xaa55
diskload.asm
disk_load :
push dx
mov ah , 0x02
mov al , dh ;
mov ch , 0x00
mov dh , 0x00
mov cl , 0x02
int 0x13
jc disk_error
pop dx
cmp dh , al
jne disk_error
ret
disk_error :
mov si , DISK_ERROR_MSG
call prints
jmp $
; Variables
DISK_ERROR_MSG db " Disk read error !" , 0
prints:
lodsb
or al, al
jz printdones
mov ah, 0eh
int 10h
jmp prints
printdones:
ret
编译命令:
nasm boot.asm -f bin -o boot.bin
nasm kernel_entry.asm -f elf64 -o kernel_entry.o
gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary
cat boot.bin kernel.bin > os.iso
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
此错误的影响是存储在可执行文件中的入口点地址将不正确。
然而,"raw"二进制文件只包含一些内存内容;它们不像 ELF 或 COFF 文件那样包含任何附加信息 - 例如入口点。
换句话说:对于 "raw" 个二进制文件 (--oformat binary
),此警告消息根本没有意义。
But when i boot my operating system, it shows an error: Disk read error!
我不确定,但有两个可能的错误:
您确定 ES
寄存器包含正确的值吗?
(如果你想加载你的内核到绝对地址 0x1000,你必须设置 ES
为 0。)
许多驱动器类型不支持一次读取太多扇区。
(但是真正的 1440K 驱动器应该支持读取从第 2 扇区开始的 15 个扇区。)
我也有这个问题,磁盘读取错误可能是由于您的最终os图像太小而无法读取15个扇区。
如果您使用 qemu,请尝试使用 :
调整您的 os 图片大小
qemu-img resize os.iso +20K
这会将您的图片调整为 20 KB
(你可以输入你自己的值而不是 20K)。
我认为 qemu 将 os 图像视为整个磁盘,因此您应该相应地调整它的大小。
我正在为 linux 使用 Windows 10 和 Windows 子系统。 我已经开始用 Assembly 和 C 创建自己的操作系统。 我正在学习教程。 我遇到了 2 个问题。
错误一: 当我 Link 并创建 bin 文件时,我收到警告: "ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000" 这重要吗?
错误2: 编译我的代码后,没有错误。但是当我启动我的操作系统时,它显示错误:磁盘读取错误!
请帮助我。
Boot.asm
[org 0x7c00]
KERNEL_OFFSET equ 0x1000
mov [BOOT_DRIVE], dl
mov bp, 0x9000
mov sp, bp
mov si, MSG_REAL_MODE
call print
call load_kernel
call switch_to_pm
jmp $
%include "printstr.asm"
%include "diskload.asm"
[bits 16]
load_kernel :
mov si, MSG_LOAD_KERNEL
call print
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
times 510 -( $ - $$ ) db 0
dw 0xaa55
diskload.asm
disk_load :
push dx
mov ah , 0x02
mov al , dh ;
mov ch , 0x00
mov dh , 0x00
mov cl , 0x02
int 0x13
jc disk_error
pop dx
cmp dh , al
jne disk_error
ret
disk_error :
mov si , DISK_ERROR_MSG
call prints
jmp $
; Variables
DISK_ERROR_MSG db " Disk read error !" , 0
prints:
lodsb
or al, al
jz printdones
mov ah, 0eh
int 10h
jmp prints
printdones:
ret
编译命令:
nasm boot.asm -f bin -o boot.bin
nasm kernel_entry.asm -f elf64 -o kernel_entry.o
gcc -ffreestanding -c kernel.c -o kernel.o
ld -o kernel.bin -Ttext 0x1000 kernel_entry.o kernel.o --oformat binary
cat boot.bin kernel.bin > os.iso
ld: warning: cannot find entry symbol _start; defaulting to 0000000000001000
此错误的影响是存储在可执行文件中的入口点地址将不正确。
然而,"raw"二进制文件只包含一些内存内容;它们不像 ELF 或 COFF 文件那样包含任何附加信息 - 例如入口点。
换句话说:对于 "raw" 个二进制文件 (--oformat binary
),此警告消息根本没有意义。
But when i boot my operating system, it shows an error: Disk read error!
我不确定,但有两个可能的错误:
您确定
ES
寄存器包含正确的值吗?
(如果你想加载你的内核到绝对地址 0x1000,你必须设置ES
为 0。)许多驱动器类型不支持一次读取太多扇区。
(但是真正的 1440K 驱动器应该支持读取从第 2 扇区开始的 15 个扇区。)
我也有这个问题,磁盘读取错误可能是由于您的最终os图像太小而无法读取15个扇区。
如果您使用 qemu,请尝试使用 :
调整您的 os 图片大小qemu-img resize os.iso +20K
这会将您的图片调整为 20 KB (你可以输入你自己的值而不是 20K)。
我认为 qemu 将 os 图像视为整个磁盘,因此您应该相应地调整它的大小。