I'm developing on my little OS. Using Bochs emulator to run it. Currently when I generate final ELF file, GRUB inside Bochs is able to boot from it, but the problem is that currently in C code I have a variable that holds a text that will be displayed on the screen(char message[] = "some short message"
) and when I increase the size of that text, lets say I replace it with:
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?"
I get the error Error: no multiboot header found
when I try to boot my OS from GRUB. I know that GRUB seeks to find 0x1BADB002, flags and checksum in my executable and I tried to provide them, and looks like it's working well when the size of that text is small, but doesn't when it's big. Overall it should not be depended on that of course, so I'm probably messing up something while linking .o files, but I don't know what.
P.S. I am following a tutorial and am not yet very familiar with all the tools that I'm using(nasm, ld etc.), so I'd say my questions are:
- Should the multiboot header be exactly at the beginning of the executable file? Because when I tried to see the content working executable with hexdump it was not starting with something like
1B AD B0 02
- In tutorial was said that
. = 0x00100000
is needed because system itself is using bottom 1MB address-space of RAM for itself, meaning that my multiboot header will be somewhere after 1MB in the final executable? - Does C compiler(I'm using GCC 7.5.0) treat lines like
char message[] = "some short message"
differently based on the size of that message? Does it store them in defferent sections when converts code to assembler? Because when I deleted rodata section from the linker script it worked even with long message.
Thanks in advance for any help and here are some important files about the building flow:
loader.s (Initializes some things and calls kmain function from kmain.c)
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
kmain.c
int kmain() {
char message[] = "some short message";
fb_write(message, sizeof(message) - 1); // defined in another file and included
return 0;
}
link.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 */
}
}