[英]Trouble with custom OS's bootloader not jumping to kernel
I recently had an idea to start developing my own Operating System. 我最近有一个想法开始开发自己的操作系统。 After reading many articles on different sites that I thought would help me with this task, I thought I could start now. 在阅读了我认为可以帮助我完成这项任务的不同网站上的许多文章后,我想我现在可以开始了。 (I am using Ubuntu 14.10 x64 by the way) (顺便说一句,我使用的是Ubuntu 14.10 x64)
Since a floppy disk is the simplest storage medium for developing OSes, I acquired a 3.5 inch floppy disk drive. 由于软盘是开发操作系统最简单的存储介质,因此我购买了3.5英寸软盘驱动器。
I am using NASM as an assembly compiler, and qemu as an emulator. 我使用NASM作为汇编编译器,qemu作为模拟器。 Using the dd command, I cloned an existing and empty (in terms of files) floppy disk to a file called floppy.img.bak . 使用dd命令,我将一个现有的和空的(就文件而言)软盘克隆到一个名为floppy.img.bak的文件中。
After that, I wrote a simple bootloader in x86 assembly: 之后,我在x86程序集中编写了一个简单的bootloader:
bootloader.asm bootloader.asm
org 7C00h
jmp 0x0000:start ;go
msg db 'Loading Kernel...', 0
start:
;update the segment registers
mov ax, cs
mov ds, ax
mov es, ax
mov si, msg
print: ;prints a string
lodsb ;load next char
cmp al, 0 ;if null terminator...
je reset ;...jump to reset:
mov ah, 0Eh ;print AL
mov bx, 7
int 10h
jmp print ;if not null terminator, continue printing
reset: ;resets the floppy drive
mov ax, 0 ;
mov dl, 0 ;drive=0 (=A)
int 13h ;
jc reset ;if error resetting, reset again
read:
mov ax, 1000h ;ES:BX = 1000:000
mov es, ax ;es is 1000h now
mov bx, 0 ;bx is 0 now
mov ah, 2 ;load disk data into ES:BX
mov al, 1 ;load 1 sector
mov ch, 0 ;cylinder=0
mov cl, 2 ;sector=2
mov dh, 0 ;head=0
mov dl, 0 ;drive=0
int 13h ;read!
jc read ;if error then try again
jmp 1000h:0000;jump to the program
times 510-($-$$) db 0
dw 0AA55h
So far so good. 到现在为止还挺好。 My simple temporary stub kernel is as follows: 我的简单临时存根内核如下:
kernel.asm kernel.asm
kstart:
mov ah, 9
mov al, 'k'
mov bx, 7
mov cx, 5
int 10h
hang:
jmp hang
times 510-($-$$)+2 db 0
I also have a shell script to compile, write and boot this setup: 我还有一个shell脚本来编译,编写和启动这个设置:
compile-and-run.sh compile-and-run.sh
cd ~/Dev/OS # cd to here
rm asm-bin/bootloader.bin # remove old compiled bootloader
rm asm-bin/kernel.bin # remove old compiled kernel
nasm asm-src/bootloader.asm -f bin -o asm-bin/bootloader.bin # compile bootloader
nasm asm-src/kernel.asm -f bin -o asm-bin/kernel.bin # compile kernel
rm images/floppy.img # remove old floppy image
cp images/floppy.img.bak images/floppy.img # copy original floppy image to fresh one
dd if=asm-bin/bootloader.bin of=images/floppy.img bs=512 count=1 seek=0 # write bootloader to first sector
dd if=asm-bin/kernel.bin of=images/floppy.img bs=512 count=1 seek=1 # write kernel to second sector
qemu-system-i386 images/floppy.img # start qemu and boot floppy.img
Now, the expected output in qemu would be (at least what I understand): 现在,qemu的预期输出将是(至少我所理解的):
Loading Kernel...
kkkkk
But instead, it is: 但相反,它是:
Loading Kernel...
So, obviously, there is something wrong at the jump, I just don't know what. 所以,显然,跳跃有些不对劲,我只是不知道是什么。 Maybe you could help me? 也许你可以帮助我? I would appreciate it. 我会很感激。
The bootdrive is stored in dl
register but you override it to 0. bootdrive存储在dl
寄存器中,但是将其覆盖为0。
By default the bootdrive is 80h and not 0 as used by the bootloader code. 默认情况下,bootdrive为80h,而不是引导加载程序代码使用的0。
If you comment out the 2 lines 如果你注释掉2行
; mov dl, 0 ;drive=0 (=A)
It will boot as you expect. 它将按预期启动。
Fix your script, you need to run it with qemu-system-i386 -fda images/floppy.img
. 修复脚本,需要使用qemu-system-i386 -fda images/floppy.img
运行它。 Notice the -fda
parameter. 注意-fda
参数。 If you omit that, your image will be attached as hard disk and not as floppy disk, so your read will fail (since you have hard-coded the floppy drive). 如果省略,您的映像将作为硬盘而不是软盘附加,因此您的读取将失败(因为您已经对软盘驱动器进行了硬编码)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.