我正在我的小操作系统上开发。使用 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 我正在学习一个教程,但对我正在使用的所有工具(nasm、ld等)还不是很熟悉,所以我想说我的问题是:
- 多重引导标头是否应该恰好位于可执行文件的开头?因为当我尝试使用hexdump查看内容工作可执行文件时,它不是以类似的开头
1B AD B0 02
- 在教程中说这
. = 0x00100000
是必要的,因为系统本身正在为自己使用 RAM 的底部 1MB 地址空间,这意味着我的多重引导标头将在最终可执行文件中的 1MB 之后的某个位置? - 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 */
}
}