为什么我的操作系统没有被我的引导加载程序文件加载?

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

我在创建操作系统时遇到问题。 我有 2 个文件(bootloader.s && kernel.s) 但是当我编译这两个文件并执行时

as -o bootloader.o bootloader.s
ld -o bootloader.bin --oformat binary -e init -Ttext 0x7c00 -o bootloader.bin bootloader.o
qemu-system-x86_64 bootloader.bin

没有任何附加内容(只是:“从硬盘启动......”)

我在 https://openclassrooms.com/forum/sujet/asm-boot-loader-91783 上没有找到解决方案 其他教程也是如此。

bootloader.s

.code16 # use 16 bits
.set BASE, 0x1000
.set KSIZE, 1
.global init

init:
    mov $0x100, %ax
    mov %ax, %ds
    mov %ax, %es

    # initialisation du segment de pile
    mov $0x8000, %ax
    mov %ax, %ss
    mov $0xf000, %sp

    mov $0x0e,  %ah

    in  $0x64,  %al
    test    $1, %al
    jz  init_next

    in  $0x60,  %al
    cmp $224,   %al
    je  init_next

init_next:

    mov     BASE, %ax
    mov     %ax, %es
    xor     %bx, %bx

# charger le noyau
    mov $0x02, %ah
    mov KSIZE, %al
    mov $0, %ch
    mov $2, %cl
    mov $0, %dh
    mov $0, %dl
    int $0x13
    mov $'F', %al
    int $0x10


# saut vers le kernel
    jmp BASE


bootdrv: .int 0


.fill 510-(.-init), 1, 0
.word 0xaa55

.include "kernel.s"

内核.s

.code16
.global init
.org 0x1000

start:
    mov $0x1000, %ax
    mov %ax, %ds
    mov %ax, %es

    # initialisation du segment de pile
    mov $0x8000, %ax
    mov %ax, %ss
    mov $0xf000, %sp

    mov $0x0e,  %ah

    in  $0x64,  %al
    test    $1, %al
    jz  next

    in  $0x60,  %al
    cmp $224,   %al
    je  next

data:
    msg: .asciz "Hello world !"
    msg2: .asciz "I hope you're well : "
    test_int: .int 0
    #msg3: .asciz "Just a test for the size of the bootloader"

print_str:
    push %ax
    .print_str__run:
        lodsb
        cmp $0, %al
        je  .print_str__done
        int $0x10
        jmp .print_str__run
    .print_str__done:
        pop %ax
        ret

print_nl:
    push %ax
    .print_nl__run:
        mov $10, %al
        int $0x10
        mov $13, %al
        int $0x10

        pop %ax
        ret


input:
    .input__run:
        in  $0x64,  %al
        and $1, %al
        jz  .input__run

        in  $0x60,  %al # get input keyboard

        mov %al,    %bl
        cmp $0x0,   %bl
        je  .input__run

        shr $4, %bl # move to right 4 bits
        cmp $0x0, %bl
        je  .input__number

        jmp .input__letter


        .input__number:
            add $47,    %al
            int $0x10
            jmp .input__done

        .input__letter:
            cmp $0x10,  %al
            je .input__letter__a
            cmp $0x11,  %al
            je .input__letter__z
            cmp $0x12,  %al
            je .input__letter__e
            cmp $0x13,  %al
            je .input__letter__r
            cmp $0x14,  %al
            je .input__letter__t
            cmp $0x15,  %al
            je .input__letter__y
            cmp $0x16,  %al
            je .input__letter__u
            cmp $0x17,  %al
            je .input__letter__i
            cmp $0x18,  %al
            je .input__letter__o
            cmp $0x19,  %al
            je .input__letter__p
            cmp $0x1e,  %al
            je .input__letter__q
            cmp $0x1f,  %al
            je .input__letter__s
            cmp $0x20,  %al
            je .input__letter__d
            cmp $0x21,  %al
            je .input__letter__f
            cmp $0x22,  %al
            je .input__letter__g
            cmp $0x23,  %al
            je .input__letter__h
            cmp $0x24,  %al
            je .input__letter__j
            cmp $0x25,  %al
            je .input__letter__k
            cmp $0x26,  %al
            je .input__letter__l
            cmp $0x27,  %al
            je .input__letter__m
            cmp $0x2c,  %al
            je .input__letter__w
            cmp $0x2d,  %al
            je .input__letter__x
            cmp $0x2e,  %al
            je .input__letter__c
            cmp $0x2f,  %al
            je .input__letter__v
            cmp $0x30,  %al
            je .input__letter__b
            cmp $0x31,  %al
            je .input__letter__n
            cmp $0x39,  %al
            je .input__letter__space

            jmp .input__run

            .input__letter__a:
                mov $'a',   %al
                int $0x10
                jmp .input__done

            .input__letter__z:
                mov $'z',   %al
                int $0x10
                jmp .input__done

            .input__letter__e:
                mov $'e',   %al
                int $0x10
                jmp .input__done

            .input__letter__r:
                mov $'r',   %al
                int $0x10
                jmp .input__done

            .input__letter__t:
                mov $'t',   %al
                int $0x10
                jmp .input__done

            .input__letter__y:
                mov $'y',   %al
                int $0x10
                jmp .input__done

            .input__letter__u:
                mov $'u',   %al
                int $0x10
                jmp .input__done

            .input__letter__i:
                mov $'i',   %al
                int $0x10
                jmp .input__done

            .input__letter__o:
                mov $'o',   %al
                int $0x10
                jmp .input__done

            .input__letter__p:
                mov $'p',   %al
                int $0x10
                jmp .input__done

            .input__letter__q:
                mov $'q',   %al
                int $0x10
                jmp .input__done

            .input__letter__s:
                mov $'s',   %al
                int $0x10
                jmp .input__done

            .input__letter__d:
                mov $'d',   %al
                int $0x10
                jmp .input__done

            .input__letter__f:
                mov $'f',   %al
                int $0x10
                jmp .input__done

            .input__letter__g:
                mov $'g',   %al
                int $0x10
                jmp .input__done

            .input__letter__h:
                mov $'h',   %al
                int $0x10
                jmp .input__done

            .input__letter__j:
                mov $'j',   %al
                int $0x10
                jmp .input__done

            .input__letter__k:
                mov $'k',   %al
                int $0x10
                jmp .input__done

            .input__letter__l:
                mov $'l',   %al
                int $0x10
                jmp .input__done

            .input__letter__m:
                mov $'m',   %al
                int $0x10
                jmp .input__done

            .input__letter__w:
                mov $'w',   %al
                int $0x10
                jmp .input__done

            .input__letter__x:
                mov $'x',   %al
                int $0x10
                jmp .input__done

            .input__letter__c:
                mov $'c',   %al
                int $0x10
                jmp .input__done

            .input__letter__v:
                mov $'v',   %al
                int $0x10
                jmp .input__done

            .input__letter__b:
                mov $'b',   %al
                int $0x10
                jmp .input__done

            .input__letter__n:
                mov $'n',   %al
                int $0x10
                jmp .input__done

            .input__letter__space:
                mov $' ',   %al
                int $0x10
                jmp .input__done

    .input__done:
        ret

next:

.key_wait:
    in  $0x64,  %al
    and $1, %al
    jz  .key_wait

    in  $0x60,  %al

    cmp $0x10,  %al # 'a' pressed
    je .code

    mov %al,    %bl
    cmp $0x0,   %bl
    je  .key_wait

    shr $4, %bl
    cmp $0x0, %bl
    je  .number

    jmp .normal


    .number:
        add $47,    %al
        int $0x10
        jmp .key_wait

    .normal:
        int $0x10
        jmp .key_wait

.code:
    #mov $8, %al
    #mov %al, test_int
    call print_nl
    mov $msg, %si
    call print_str
    call print_nl
    mov $msg2, %si
    call print_str
    code__input:
    call input
    mov $0x0, %al

assembly bootloader
2个回答
1
投票
mov     BASE, %ax
mov     %ax, %es
xor     %bx, %bx

看到kernel.s文件有一个

.org 0x1000
指令,我们知道
.set BASE, 0x1000
指的是线性地址0x1000。为了让 BIOS 加载内核,我们应该将
%es:%bx
设置为 0x0000:0x1000。

xor %ax, %ax
mov %ax, %es
mov BASE, %bx

init:
    mov $0x100, %ax
    mov %ax, %ds
    mov %ax, %es

因为您的 bootloader.s 文件使用原点 7C00h,所以

%ds
%es
的正确设置为零:

init:
    xor %ax, %ax
    mov %ax, %ds
    mov %ax, %es

.org 0x1000

start:
    mov $0x1000, %ax
    mov %ax, %ds
    mov %ax, %es

因为您的 kernel.s 文件使用

.org 0x1000
,所以
%ds
%es
的正确设置为零:

.org 0x1000

start:
    xor %ax, %ax
    mov %ax, %ds
    mov %ax, %es

mov $0, %dl
int $0x13
mov $'F', %al
int $0x10

int $0x10
应该做什么?
如果
int $0x13
调用成功,则
%ah
仍将包含 0x02,但这将导致无意义的 SetCursorPosition 调用,如果
int $0x13
调用不成功,则
%ah
将保存一个状态字节,该状态字节将导致调用一些随机视频 BIOS 调用!

提示1:请务必检查BIOS向您报告的进位标志,以便您可以处理错误...
提示 2:最好省略

mov $0, %dl
指令并使用 BIOS 在将控制权传递给引导加载程序时放入
%dl
寄存器中的值。


    cmp $224,   %al
    je  next

data:
    msg: .asciz "Hello world !"

%al
不等于224时会发生什么?执行在某些数据中失败,绝对不是代码!

我建议一步一步地进行,并简化当前的代码(两个文件)以不使用那些与键盘相关的端口
在需要键盘输入的地方,您应该使用 BIOS(就像您已经在使用其他任何东西一样):

mov  ah, 00h   ; BIOS.WaitKeyboardKeypress
int  16h       ; -> AH is scancode, AL is ASCII code

0
投票

当你快乐时,你会喜欢音乐,但当你悲伤时,你会理解歌词 จีจี https://google.co.th/

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