Assembly 为什么';我的引导加载程序不能加载我的内核吗?

Assembly 为什么';我的引导加载程序不能加载我的内核吗?,assembly,operating-system,x86-16,bootloader,Assembly,Operating System,X86 16,Bootloader,我已经编写了在汇编上引导操作系统的最低实现: [BITS 16] [ORG 0x7C00] start: mov ax, cs mov ds, ax mov ss, ax mov sp, start mov ax, 0x1100 mov es, ax mov bx, 0x0000 mov dl, 1 mov dh, 0 mov ch, 0 mov cl, 2 mov al, 1 mov ah, 0x02 int 0x13 mov ax, 0x1200 mov

我已经编写了在汇编上引导操作系统的最低实现:

    [BITS 16]
[ORG 0x7C00]
start:
mov ax, cs 
mov ds, ax  
mov ss, ax 
mov sp, start 

mov ax, 0x1100
mov es, ax
mov bx, 0x0000
mov dl, 1 
mov dh, 0 
mov ch, 0 
mov cl, 2 
mov al, 1 
mov ah, 0x02 
int 0x13 

mov ax, 0x1200
mov es, ax
mov bx, 0x0000
mov dl, 1
mov dh, 0
mov ch, 0
mov cl, 3
mov al, 1
mov ah, 0x02
int 0x13


cli
lgdt [gdt_info]
in al, 0x92
or al, 2
out 0x92, al    
mov eax, cr0
or al, 1
mov cr0, eax
jmp 0x8:protected_mode 
gdt:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=1(code), Access=00A, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
;base=0, size=4Gb, P=1, DPL=0, S=1(user),
;Type=0(data), Access=0W0, G=1, B=32bit
db 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
gdt_info: 
dw gdt_info - gdt
dw gdt, 0
[BITS 32]
protected_mode:
mov ax, 0x10
mov es, ax
mov ds, ax
mov ss, ax
call 0x11000
times (512 - ($ - start) - 2) db 0 
db 0x55, 0xAA
内核在C中的最小实现:

extern "C" int kmain();
__declspec(naked) void startup()
{
    __asm {
        call kmain;
    }
}
#define VIDEO_BUF_PTR (0xb8000)
void out_str(int color, const char* ptr, unsigned int strnum)
{
    unsigned char* video_buf = (unsigned char*)VIDEO_BUF_PTR;
    video_buf += 80 * 2 * strnum;
    while (*ptr)
    {
        video_buf[0] = (unsigned char)*ptr;
        video_buf[1] = color;
        video_buf += 2;
        ptr++;
    }
}
extern "C" int kmain()
{
    const char* hello = "Welcome to HelloWorldOS (gcc edition)!";
    out_str(0x07, hello, 0);
    while (1)
    {
        __asm hlt;
    }
    return 0;
}
用MicrosoftC编译器编译内核 后备箱顶部:Yasm 要从PE内核中获取数据,请使用dumpbin并获取:

Microsoft (R) COFF/PE Dumper Version 14.28.29335.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file kernel.bin

PE signature found

File Type: EXECUTABLE IMAGE

FILE HEADER VALUES
             14C machine (x86)
               2 number of sections
        604FC5B3 time date stamp Mon Mar 15 23:38:11 2021
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
             103 characteristics
                   Relocations stripped
                   Executable
                   32 bit word machine

OPTIONAL HEADER VALUES
             10B magic # (PE32)
           14.28 linker version
             200 size of code
             200 size of initialized data
               0 size of uninitialized data
            1000 entry point (00011000)
            1000 base of code
            2000 base of data
           10000 image base (00010000 to 00012FFF)
            1000 section alignment
             200 file alignment
            6.00 operating system version
            0.00 image version
            6.00 subsystem version
               0 Win32 version
            3000 size of image
             200 size of headers
             636 checksum
               1 subsystem (Native)
             500 DLL characteristics
                   NX compatible
                   No structured exception handler
          100000 size of stack reserve
            1000 size of stack commit
          100000 size of heap reserve
            1000 size of heap commit
               0 loader flags
              10 number of directories
               0 [       0] RVA [size] of Export Directory
               0 [       0] RVA [size] of Import Directory
               0 [       0] RVA [size] of Resource Directory
               0 [       0] RVA [size] of Exception Directory
               0 [       0] RVA [size] of Certificates Directory
               0 [       0] RVA [size] of Base Relocation Directory
            2044 [      1C] RVA [size] of Debug Directory
               0 [       0] RVA [size] of Architecture Directory
               0 [       0] RVA [size] of Global Pointer Directory
               0 [       0] RVA [size] of Thread Storage Directory
               0 [       0] RVA [size] of Load Configuration Directory
               0 [       0] RVA [size] of Bound Import Directory
               0 [       0] RVA [size] of Import Address Table Directory
               0 [       0] RVA [size] of Delay Import Directory
               0 [       0] RVA [size] of COM Descriptor Directory
               0 [       0] RVA [size] of Reserved Directory


SECTION HEADER #1
   .text name
      AE virtual size
    1000 virtual address (00011000 to 000110AD)
     200 size of raw data
     200 file pointer to raw data (00000200 to 000003FF)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         Execute Read

SECTION HEADER #2
   .data name
      B0 virtual size
    2000 virtual address (00012000 to 000120AF)
     200 size of raw data
     400 file pointer to raw data (00000400 to 000005FF)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         Read Write

  Debug Directories

        Time Type        Size      RVA  Pointer
    -------- ------- -------- -------- --------
    604FC5B3 coffgrp       50 00002060      460

  Summary

        1000 .data
        1000 .text
作为仿真器,请使用Qemu 因此,我得到:

Booting from Hard disk...
Boot failed: could not read the boot disk

Booting from from Floppy...
没别的了。那么为什么我的操作系统不工作呢?我认为问题在于它是引导程序,但我不确定。(我只是开始学习操作系统,所以我对它了解不多)。我必须用我所有的上限条件运行它

只需输入

qemu-system-x86_64 -boot order=ab -drive file=boot.BIN,format=raw,index=0,if=floppy -drive file=kernel.BIN,format=raw,index=1,if=floppy -L "C:\Program Files\qemu"
而不是

qemu-system-x86_64 -fda boot.BIN -fdb kernel.BIN -L "C:\Program Files\qemu"

首先,假设CS==0,将DS设置为CS。如果使用[ORG 0x7C00],则必须假定CS为0。情况可能并非如此。不要使用当前CS值设置段寄存器。使用已知值直接设置它们。其次,将DL寄存器设置为1以调用BIOS读取扇区。值1是第二张软盘。你有两个软盘驱动器吗?Bochs说它是从硬盘启动的,尽管你正在读第二张软盘。谢谢你的回答。因此,为了引导操作系统,我使用2张软盘,第一张是引导加载程序,第二张是内核。(使用commnad:qemu-system-x86_64-fda boot.BIN-fdb kernel.BIN-L“C:\Program Files\qemu”运行)没错,qemu,不是Bochs。无论如何,首先告诉QEMU您正在启动软盘,第一个错误就会发生。第二,如何将引导代码和内核文件放到软盘映像上?你能确认它们在正确的位置吗?你有没有一步一步地检查代码,看看错误在哪里,看看会发生什么?此外,PE文件上有一个头。您正在将该标头写入软盘映像吗?你需要跳过标题吗?只是跟进。你发现错误了吗?如果没有,你能把这两张软盘图片贴到某个地方让我们看一下吗?很抱歉,我只是需要很多时间来理解它(所以,首先,我想我告诉QEMU我是从软盘上用comand(-fda-fdb)引导的),我找不到关于它的更多信息。我还确信它们位于正确的插槽中,booter位于第一个插槽(0),内核位于第二个插槽(0)。顺便说一句,我真的不知道如何消除汇编代码的bug,我只是输出符号并试图注意错误发生的位置,但我没有找到任何东西。