自定义内核不读取全局变量和 char*

Custom kernel not reading global variables and char*

我有一个自定义 bootloader 启动到自定义内核。我正在用 C 编写,现在程序集已经不在了。

到目前为止,局部变量和方法工作正常,但编译时无法识别全局变量,运行。

我有这三个功能:

void SetChar(int VidIndex, char c) {    //Print a single char to a mem index set by VidIndex : WORKS!!
    char* vidPtr = (char*)0xb8000;
    vidPtr += VidIndex * 2;
    *vidPtr = c;
}

void PrintString(char* string) {        //Print 20 chars of a string, as a test :   NOT WORKS
    char* ptr = string;
    for (int t = 0; t < 20; t++) {
        SetChar(t, *ptr);
        ptr++;
    }
}

void ClearScreen() {                //Sets all chars in Video Memory to empty : WORKS!!

    for (char* ptr = (char*)0xb8000; ptr < (char*)(0xb8000 + 4000); ptr+=0x02) {
        *ptr = ' ';
    }
}

使用像这样的主函数工作正常并且可以做我想要的:

void _main() {
    
    ClearScreen();

    SetChar(5, 'H');
    SetChar(6, 'e');
    SetChar(7, 'l');
    SetChar(8, 'l');
    SetChar(9, 'o');

    return ;
}

然而, 如果我这样做:

char* WelcomeString = "Welcome to my 32 bit OS with a C kernel.";

void _main() {
    
    ClearScreen();

    PrintString(WelcomeString);

    return ;
}

然后图像是完全黑色的,上面什么也没有。 查看二进制数据表明 char* 字节未编译到其中。这也不适用于其他全局变量。 我正在像这样在 .bat 中编译和链接:

nasm "C:\Users\Braiden\source\repos\Operating System\Bootloader.asm" -o bootloader.bin -f bin -i "C:\Users\Braiden\source\repos\Operating System"

nasm "C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm" -f elf64 -o kernel_entry.o

nasm "C:\Users\Braiden\source\repos\Operating System\padding.asm" -o padding.bin -f bin

gcc -ffreestanding -c "C:\Users\Braiden\source\repos\Operating System\Kernel.c" -o kernel.o

ld -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o 
objcopy -O binary -j .text  kernel.tmp kernel.bin

copy /b bootloader.bin+kernel.bin+padding.bin os-image.img

pause

它这样做的原因可能是什么?这对我来说非常 st运行ge。 如果需要,我愿意提供更多信息。我只是不确定我需要提供什么。

编辑: Bootloader.asm

        global _start

_start:

[bits 16]
[org 0x7c00]

    KERNEL_ENTRY equ 0x1000
    mov bp, 0x8000
    mov sp, bp

    mov bx, welcomeString
    call print_func

    mov [ BOOT_DRIVE ], dl                  ; BIOS stores our boot drive in DL , so it ’s
                                            ; best to remember this for later.
    mov bp, 0x7c00                          ; Here we set our stack safely out of the
    mov sp, bp                              ; way , at 0 x8000
    mov bx, KERNEL_ENTRY                    ; Load 5 sectors to 0x0000 (es):KERNEL_ENTRY (bx)
    mov dh, 41                              ; from the boot disk.
    mov dl, [ BOOT_DRIVE ]
    call ReadDisk

    mov bx, readSuccessString               ; Print Success after reading disk
    call print_func

    mov bx, 0x7e00                          ; Let's see if we loaded the area
    call print_hex_func                     ; correctly
    call print_newline_func
    call PrintAddress

    call print_newline_func

    jmp switch_to_pm

    jmp $

%include "io.asm"
%include "print.asm"
%include "gdt.asm"

welcomeString:
    db 'Hello. Welcome to OS', 13, 10,0

readSuccessString:
    db 'Disk read Success', 13, 10, 0

switch_to_pm:
    cli

    lgdt [gdt_descriptor]
    mov eax, cr0
    or eax, 0x1
    mov cr0, eax

    jmp CODE_SEG:init_pm
    
[bits 32]

init_pm:

    mov ax, DATA_SEG
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000
    mov esp, ebp

    jmp BEGIN_PM

BEGIN_PM:

    jmp KERNEL_ENTRY    ; jump out of our 512 byte sector into the rest of our loaded memory
                        ; so we have much more space to work, and start the kernel
    jmp $

MSG_PM:
    db 'success', 0

times 510-($-$$) db 0

dw 0xaa55

kernel_entry.asm

[bits 32]
[extern _main]
call _main
jmp $

gcc -v 输出:(使用 MinGW)

Using built-in specs.
COLLECT_GCC=C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\gcc.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable-static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgversion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L/c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'
 C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/cc1.exe -quiet -v -iprefix C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/ -D_REENTRANT C:\Users\Braiden\source\repos\Operating System\Kernel.c -quiet -dumpbase Kernel.c -mtune=core2 -march=nocona -auxbase-strip kernel.o -version -ffreestanding -o C:\Users\Braiden\AppData\Local\Temp\ccTxrZFP.s
GNU C17 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) version 8.1.0 (x86_64-w64-mingw32)
        compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/include"
ignoring nonexistent directory "C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../include"
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed"
ignoring duplicate directory "C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "C:/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/mingw/include"
#include "..." search starts here:
#include <...> search starts here:
 C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include
 C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/include-fixed
 C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/include
End of search list.
GNU C17 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) version 8.1.0 (x86_64-w64-mingw32)
        compiled by GNU C version 8.1.0, GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version isl-0.18-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 985ce7ae6dd3a696cd146ca9896b0035
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'
 C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/as.exe -v -o kernel.o C:\Users\Braiden\AppData\Local\Temp\ccTxrZFP.s
GNU assembler version 2.30 (x86_64-w64-mingw32) using BFD version (GNU Binutils) 2.30
COMPILER_PATH=C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../libexec/gcc/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/;C:/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../
COLLECT_GCC_OPTIONS='-v' '-ffreestanding' '-c' '-o' 'kernel.o' '-mtune=core2' '-march=nocona'

objdump -x kernel.tmp

kernel.tmp:     file format pei-x86-64
kernel.tmp
architecture: i386:x86-64, flags 0x00000132:
EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
start address 0x0000000100001000

Characteristics 0x227
        relocations stripped
        executable
        line numbers stripped
        large address aware
        debugging information removed

Time/Date               Sun Jun 21 02:05:38 2020
Magic                   020b    (PE32+)
MajorLinkerVersion      2
MinorLinkerVersion      30
SizeOfCode              00000200
SizeOfInitializedData   00000a00
SizeOfUninitializedData 00000000
AddressOfEntryPoint     00000000ffc01000
BaseOfCode              00000000ffc01000
ImageBase               0000000000400000
SectionAlignment        0000000000001000
FileAlignment           0000000000000200
MajorOSystemVersion     4
MinorOSystemVersion     0
MajorImageVersion       0
MinorImageVersion       0
MajorSubsystemVersion   5
MinorSubsystemVersion   2
Win32Version            00000000
SizeOfImage             ffc07000
SizeOfHeaders           00000400
CheckSum                00006de2
Subsystem               00000003        (Windows CUI)
DllCharacteristics      00000000
SizeOfStackReserve      0000000000200000
SizeOfStackCommit       0000000000001000
SizeOfHeapReserve       0000000000100000
SizeOfHeapCommit        0000000000001000
LoaderFlags             00000000
NumberOfRvaAndSizes     00000010

The Data Directory
Entry 0 0000000000000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000ffc06000 00000014 Import Directory [parts of .idata]
Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000ffc04000 00000030 Exception Directory [.pdata]
Entry 4 0000000000000000 00000000 Security Directory
Entry 5 0000000000000000 00000000 Base Relocation Directory [.reloc]
Entry 6 0000000000000000 00000000 Debug Directory
Entry 7 0000000000000000 00000000 Description Directory
Entry 8 0000000000000000 00000000 Special Directory
Entry 9 0000000000000000 00000000 Thread Storage Directory [.tls]
Entry a 0000000000000000 00000000 Load Configuration Directory
Entry b 0000000000000000 00000000 Bound Import Directory
Entry c 0000000000000000 00000000 Import Address Table Directory
Entry d 0000000000000000 00000000 Delay Import Directory
Entry e 0000000000000000 00000000 CLR Runtime Header
Entry f 0000000000000000 00000000 Reserved

There is an import table in .idata at 0x6000

The Import Tables (interpreted .idata section contents)
 vma:            Hint    Time      Forward  DLL       First
                 Table   Stamp     Chain    Name      Thunk
 ffc06000       00000000 00000000 00000000 00000000 00000000

The Function Table (interpreted .pdata section contents)
vma:                    BeginAddress     EndAddress       UnwindData
 0000000100004000:      0000000100001010 0000000100001044 0000000100005000
  has negative begin address
  has negative end address
  has negative unwind address
 000000010000400c:      0000000100001044 000000010000108b 000000010000500c
  has negative begin address
  has negative end address
  has negative unwind address
 0000000100004018:      000000010000108b 00000001000010ba 0000000100005018
  has negative begin address
  has negative end address
  has negative unwind address
 0000000100004024:      00000001000010ba 00000001000010dd 0000000100005024
  has negative begin address
  has negative end address
  has negative unwind address

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000100  0000000100001000  0000000100001000  00000400  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000010  0000000100002000  0000000100002000  00000600  2**4
                  CONTENTS, ALLOC, LOAD, DATA
  2 .rdata        00000070  0000000100003000  0000000100003000  00000800  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .pdata        00000030  0000000100004000  0000000100004000  00000a00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .xdata        00000030  0000000100005000  0000000100005000  00000c00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .idata        00000014  0000000100006000  0000000100006000  00000e00  2**2
                  CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000000000000013 Kernel.c
File
[  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x0000000000000010 SetChar
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[  4](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x0000000000000044 PrintString
[  5](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x000000000000008b ClearScreen
[  6](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000000000ba _main
[  7](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000010 .text
AUX scnlen 0xcd nreloc 1 nlnno 0
[  9](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000000 .data
AUX scnlen 0x8 nreloc 1 nlnno 0
[ 11](sec  5)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000000 .xdata
AUX scnlen 0x30 nreloc 0 nlnno 0
[ 13](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000000 .pdata
AUX scnlen 0x30 nreloc 12 nlnno 0
[ 15](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000000 .rdata
AUX scnlen 0x29 nreloc 0 nlnno 0
[ 17](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x0000000000000030 .rdata$zzz
AUX scnlen 0x3f nreloc 0 nlnno 0
[ 19](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x0000000000000015 C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm
File
[ 21](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 ___RUNTIME_PSEUDO_RELOC_LIST__
[ 22](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __data_start__
[ 23](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000000f0 ___DTOR_LIST__
[ 24](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___tls_start__
[ 25](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000400000 __ImageBase
[ 26](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 __rt_psrelocs_start
[ 27](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __dll_characteristics__
[ 28](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 __size_of_stack_commit__
[ 29](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000200000 __size_of_stack_reserve__
[ 30](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000005 __major_subsystem_version__
[ 31](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xl_start__
[ 32](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xi_start__
[ 33](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xi_end__
[ 34](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __bss_start__
[ 35](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 ___RUNTIME_PSEUDO_RELOC_LIST_END__
[ 36](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 __size_of_heap_commit__
[ 37](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xp_start__
[ 38](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xp_end__
[ 39](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __dll__
[ 40](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __minor_os_version__
[ 41](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000400000 __image_base__
[ 42](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 __section_alignment__
[ 43](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000014 __IAT_end__
[ 44](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 __RUNTIME_PSEUDO_RELOC_LIST__
[ 45](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 WelcomeString
[ 46](sec  2)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000010 __data_end__
[ 47](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000000e0 __CTOR_LIST__
[ 48](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __bss_end__
[ 49](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xc_end__
[ 50](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xc_start__
[ 51](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000000e0 ___CTOR_LIST__
[ 52](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __rt_psrelocs_size
[ 53](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000200 __file_alignment__
[ 54](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000004 __major_os_version__
[ 55](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000014 __IAT_start__
[ 56](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 __end__
[ 57](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000000000f0 __DTOR_LIST__
[ 58](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000100000 __size_of_heap_reserve__
[ 59](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xt_start__
[ 60](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000003 __subsystem__
[ 61](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___tls_end__
[ 62](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __major_image_version__
[ 63](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __loader_flags__
[ 64](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 __rt_psrelocs_end
[ 65](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000002 __minor_subsystem_version__
[ 66](sec -1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000000 __minor_image_version__
[ 67](sec  3)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000000070 __RUNTIME_PSEUDO_RELOC_LIST_END__
[ 68](sec  6)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000000000001000 ___crt_xt_end__

确保您的自定义引导加载程序正在读取整个内核。您是否读取了足够多的扇区以确保整个内核都在内存中?我可以从你所展示的内容中识别出来的一个问题是你如何生成 kernel.bin。你这样做:

objcopy -O binary -j .text  kernel.tmp kernel.bin

这只会将 .text 部分(代码)放入 kernel.bin 中,仅此而已。您未打印的字符串可能在您忽略包含在内核中的 .rdata* 部分中。我将包括所有部分:

objcopy -O binary kernel.tmp kernel.bin

这似乎与另一个最近已删除的 SO 问题有关,该问题非常相似并交叉发布到 OSDev Forum。那里的问题似乎与这里相同。


原始问题已根据要求进行了修改,提供了更多详细信息。正在读取的扇区数不足以覆盖内核的大小。

发现了另一个问题。编译器是64位的MinGWWindows编译器;引导加载程序仅将处理器置于 32 位保护模式;并且生成的代码是 64 位代码。您无法在 32 位保护模式下正确 运行 64 位代码。该代码可能部分 运行 正确,但它最终会表现出异常和不需要的行为。

您的选择是将处理器置于 64-bit long mode as part of your custom bootloader or have your compiler, assembler, and linker generate 32-bit objects and executables. I touch on this issue in another related

您可以更改 nasm 以使用 -felf32 到 assemble 以使用 32 位对象。由于您使用的是 Windows 本机 GCC 编译器,因此您也可以使用 -fwin32。要将 GCC 代码编译为 32 位,您可以使用 -m32 选项,而链接器 (ld) 需要 -mi386pe 选项。当涉及 OSDev with Windows 编译器时,您可能希望与链接一起使用的另一个选项是 LD 的 -N 选项,它定义为:

-N, --omagic Do not page align data, do not make text readonly

综上所述,如果生成 32 位代码,使用 i386 或 i686 ELF 交叉编译器,如果针对 [=75 的 64 位代码,则使用 64 位 ELF 交叉编译器,可以省去很多麻烦=] 发展。有关 building/using Windows 交叉编译器的更多信息,请参阅此 tutorial and the OSDev wiki has a section on GCC cross compilers 大体。


附加信息

如果生成 32 位 Windows 对象和可执行文件,全局范围内的非静态函数需要在它们前面加上 _。这些下划线由 GCC 自动生成,但在您从汇编代码中引用它们时必须添加。这同样适用于您创建的将从 C 代码调用的汇编函数。如果您编译并 assemble 您的代码,您将得到一个未定义的引用,因为您这样声明 main

void _main() {

GCC MinGW 编译器将在开头附加下划线,并将函数命名为 __main。您需要修改汇编代码以使用 __main 而不是像您的代码当前那样使用 _main 。但更容易的是将声明更改为:

void main() {

这将生成一个名为 _main 的函数,这是您的汇编代码当前期望的函数名称。

64 位 Windows 对象和可执行文件不需要或生成全局范围内带有前缀 _ 的函数。这就是生成 64 位代码时这不是问题的原因。

我一直在编译 64 位二进制文​​件,同时我启动到 32 位保护模式。以 32 位编译和链接它们解决了这个问题。这引发了外部函数前缀“_”的另一个问题,仅通过更新方法名称修复了该问题,因此前缀不会导致问题。

我最后的编译和链接命令:

nasm "C:\Users\Braiden\source\repos\Operating System\Bootloader.asm" -o bootloader.bin -f bin -i "C:\Users\Braiden\source\repos\Operating System"

nasm "C:\Users\Braiden\source\repos\Operating System\kernel_entry.asm" -f elf32 -o kernel_entry.o

nasm "C:\Users\Braiden\source\repos\Operating System\padding.asm" -o padding.bin -f bin

gcc -ffreestanding -m32 -c "C:\Users\Braiden\source\repos\Operating System\Kernel.c" -o kernel.o 

ld -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o -mi386pe

objcopy -O binary kernel.tmp kernel.bin

copy /b bootloader.bin+kernel.bin+padding.bin os-image.img