1

我正在我的小操作系统上开发。使用 Bochs 模拟器运行它。目前,当我生成最终的 ELF 文件时,Bochs 中的 GRUB 可以从中启动,但问题是目前在 C 代码中,我有一个变量,其中包含将显示在屏幕上的文本(char message[] = "some short message"),当我增加大小时在该文本中,可以说我将其替换为:

char message[] = "This is going to be a very very long line because I want to test how does framebuffer perform when we are exceeding size of one line, will this part occur on the second line?"

Error: no multiboot header found当我尝试从 GRUB 引导我的操作系统时出现错误。我知道 GRUB 试图在我的可执行文件中找到0x1BADB002标志校验和,并且我尝试提供它们,并且看起来当文本的大小很小时它运行良好,但当它很大时却不行。总的来说,它当然不应该依赖于此,所以我可能在链接.o文件时搞砸了一些东西,但我不知道是什么。

PS 我正在学习一个教程,但对我正在使用的所有工具(nasmld等)还不是很熟悉,所以我想说我的问题是:

  1. 多重引导标头是否应该恰好位于可执行文件的开头?因为当我尝试使用hexdump查看内容工作可执行文件时,它不是以类似的开头1B AD B0 02
  2. 在教程中说这. = 0x00100000是必要的,因为系统本身正在为自己使用 RAM 的底部 1MB 地址空间,这意味着我的多重引导标头将在最终可执行文件中的 1MB 之后的某个位置?
  3. C 编译器(我使用的是 GCC 7.5.0)是否会char message[] = "some short message"根据消息的大小对行进行不同的处理?将代码转换为汇编程序时,它是否将它们存储在不同的部分中?因为当我从链接器脚本中删除rodata部分时,它甚至可以使用长消息。

在此先感谢您的帮助,以下是有关构建流程的一些重要文件:

loader.s(初始化一些东西并从kmain.c调用kmain函数)

global loader

MAGIC_NUMBER equ 0x1BADB002 
FLAGS        equ 0x0
CHECKSUM     equ -MAGIC_NUMBER

KERNEL_STACK_SIZE equ 65536

section .bss
align 4
kernel_stack:
    resb KERNEL_STACK_SIZE

section .text:
align 4
    dd MAGIC_NUMBER
    dd FLAGS
    dd CHECKSUM


loader:
    mov esp, kernel_stack + KERNEL_STACK_SIZE   ; setup stack

    extern kmain                               ; hope this will be visible while linking :V
    call kmain

    mov eax, 0xCAFEBABE                        ; If eax is filled with this value at the end, it will mean that call to kmain succeeded!

.loop:
    jmp .loop

主程序

int kmain() {
    char message[] = "some short message";
    fb_write(message, sizeof(message) - 1); // defined in another file and included

    return 0;
}

链接.ld

ENTRY(loader)                /* the name of the entry label */

SECTIONS {
    . = 0x00100000;          /* the code should be loaded at 1 MB */

    .text ALIGN (0x1000) :   /* align at 4 KB */
    {
        *(.text)             /* all text sections from all files */
    }

    .rodata ALIGN (0x1000) : /* align at 4 KB */
    {
        *(.rodata*)          /* all read-only data sections from all files */
    }

    .data ALIGN (0x1000) :   /* align at 4 KB */
    {
        *(.data)             /* all data sections from all files */
    }

    .bss ALIGN (0x1000) :    /* align at 4 KB */
    {
        *(COMMON)            /* all COMMON sections from all files */
        *(.bss)              /* all bss sections from all files */
    }
}
4

0 回答 0