自定义操作系统的bootloader不能跳转到内核

我最近有一个想法,开始开发我自己的操作系统。 在阅读过不同网站上的很多文章后,我认为我可以从现在开始。 (我正在使用Ubuntu 14.10 x64)

由于软盘是开发操作系统最简单的存储介质,所以我购买了3.5英寸的软盘驱动器。

我正在使用NASM作为汇编编译器,并将qemu作为模拟器。 使用dd命令,我克隆了一个名为floppy.img.bak的文件的现有和空(在文件方面)软盘。

之后,我在x86汇编中写了一个简单的bootloader:

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 

到现在为止还挺好。 我简单的临时存根内核如下所示:

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 

我也有一个shell脚本来编译,写入和启动这个设置:

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 

现在,qemu的预期输出是(至less我所理解的):

 Loading Kernel... kkkkk 

但相反,它是:

 Loading Kernel... 

所以很显然,跳跃是有问题的,我只是不知道是什么。 也许你可以帮我吗? 我会很感激。

bootdrive存储在dl寄存器中,但是您将其覆盖为0。
默认情况下,引导加载程序代码使用的是80h而不是0。
如果你注释掉了2行

 ; mov dl, 0 ;drive=0 (=A) 

它会像你期望的那样启动。

修复你的脚本,你需要使用qemu-system-i386 -fda images/floppy.img来运行它。 注意-fda参数。 如果你省略了,你的图像将被作为硬盘而不是软盘,所以你的读取将失败(因为你已经对硬盘进行了硬编码)。