Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 自定义操作系统出现问题';s引导加载程序未跳转到内核_Linux_Assembly_Bootloader - Fatal编程技术网

Linux 自定义操作系统出现问题';s引导加载程序未跳转到内核

Linux 自定义操作系统出现问题';s引导加载程序未跳转到内核,linux,assembly,bootloader,Linux,Assembly,Bootloader,我最近有了一个想法,开始开发自己的操作系统。 在不同的网站上阅读了许多我认为可以帮助我完成这项任务的文章后,我想我现在可以开始了。(顺便说一下,我正在使用Ubuntu 14.10 x64) 因为软盘是开发操作系统最简单的存储介质,所以我买了一个3.5英寸的软盘驱动器 我使用NASM作为汇编编译器,使用qemu作为仿真器。 使用dd命令,我将一张现有的空(文件)软盘克隆到一个名为floppy.img.bak的文件中 之后,我在x86汇编中编写了一个简单的引导加载程序: bootloader.asm

我最近有了一个想法,开始开发自己的操作系统。 在不同的网站上阅读了许多我认为可以帮助我完成这项任务的文章后,我想我现在可以开始了。(顺便说一下,我正在使用Ubuntu 14.10 x64)

因为软盘是开发操作系统最简单的存储介质,所以我买了一个3.5英寸的软盘驱动器

我使用NASM作为汇编编译器,使用qemu作为仿真器。 使用dd命令,我将一张现有的空(文件)软盘克隆到一个名为floppy.img.bak的文件中

之后,我在x86汇编中编写了一个简单的引导加载程序:

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
kstart:
    mov ah, 9
    mov al, 'k'
    mov bx, 7
    mov cx, 5
    int 10h

hang:
    jmp hang

times 510-($-$$)+2 db 0
到目前为止还不错。 我的简单临时存根内核如下所示:

kernel.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
kstart:
    mov ah, 9
    mov al, 'k'
    mov bx, 7
    mov cx, 5
    int 10h

hang:
    jmp hang

times 510-($-$$)+2 db 0
我还有一个shell脚本来编译、编写和启动此设置:

编译并运行.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的预期输出将是(至少我所理解的):

但事实是:

Loading Kernel...
所以,很明显,跳跃时有点不对劲,我不知道是什么。
也许你能帮我?非常感谢。

修复您的脚本,您需要使用
qemu-system-i386-fda images/floppy.img运行它。请注意
-fda
参数。如果忽略此项,图像将作为硬盘而不是软盘附加,因此读取将失败(因为您已对软盘驱动器进行了硬编码)。

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

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

它将按您预期的方式启动。

我会让您的启动代码为流程中的每个步骤打印一个字母,以便您更好地了解应该在哪里查找。如果文件系统相同,这是否重要?它在没有这个参数的情况下工作。不客气!这只是使代码正常工作的一种简单方法,但是如果您使用更复杂的引导加载程序,则需要存储dl(如中所示)