Page 1 of 2

GRUB - no multiheader found

Posted: Tue Jun 29, 2021 5:13 pm
by Ovid
Hello, I compile my OS project using this cmake code:

Code: Select all

cmake_minimum_required(VERSION 3.7.2)

# Set the active output directories:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build/x86_64/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY build/x86_64/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/x86_64/bin)

project(kernel)

enable_language(ASM_NASM)

set(KERNEL_BIN "kernel.bin")
set(KERNEL_ISO "kernel.iso")
set(KERNEL_LIB "kernel")

set(LINKER_SCRIPT targets/x86_64/linker.ld)
set(GRUB_CFG targets/x86_64/iso/boot/grub/grub.cfg)

set(CMAKE_C_FLAGS "-c -ffreestanding")
set(CMAKE_ASM_FLAGS "{CMAKE_ASM_FLAGS} -f elf64")

set(CMAKE_C_COMPILER "x86_64-elf-gcc")
set(CMAKE_LINKER "x86_64-elf-ld")

file(GLOB BOOT_ASM_MODULES src/impl/x86_64/boot/*.asm)
file(GLOB KERNEL_C_MODULES src/impl/kernel/*.c)
file(GLOB X86_64_C_MODULES src/impl/x86_64/*.c)

add_library(
    ${KERNEL_LIB}

    STATIC

    ${BOOT_ASM_MODULES}
    ${KERNEL_C_MODULES}
    ${X86_64_C_MODULES}
    )

include_directories(src/intf)
target_include_directories(${KERNEL_LIB} PUBLIC src/intf)

add_custom_command(TARGET ${KERNEL_LIB} POST_BUILD
    COMMAND mkdir -p dist/x86_64
    COMMAND x86_64-elf-ld -n -o dist/x86_64/${KERNEL_BIN} -T ${LINKER_SCRIPT} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${KERNEL_LIB}.a
	COMMAND cp dist/x86_64/${KERNEL_BIN} targets/x86_64/iso/boot/${KERNEL_BIN}
	COMMAND grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/${KERNEL_ISO} targets/x86_64/iso
    )
When I run the .iso file that was built, I get these errors:
error: no multiheader found.
error: you need to load the kernel first.
What could cause those problems?

Here is the grub.cfg file:

Code: Select all

# Nobody knows what these lines do:
set timeout=0
set default=0

# Set the name of the OS in the boot menu:
menuentry "LearnOS" {
    multiboot2 /boot/kernel.bin  # Set the binary in this location.
    boot
}
And here is the headers asm file:

Code: Select all

; Constants:
MAGIC_NUMBER equ 0xe85250d6
CHECKSUM_INITIALIZER equ 0x100000000
HEADER_LENGTH equ (header_end - header_start)

; Name the Section:
section .multiboot_header

; Header Start:
header_start:
    ; Magic Number:
    dd MAGIC_NUMBER  ; Multiboot2

    ; Architecture:
    dd 0  ; Protected mode i386

    ; Header Length:
    dd HEADER_LENGTH

    ; Checksum:
    dd CHECKSUM_INITIALIZER - (MAGIC_NUMBER + 0 + HEADER_LENGTH)

    ; End Tag:
    dw 0
    dw 0
    dd 8

header_end:
And here is the linker code:

Code: Select all

/* Specify where the entry point is (start): */
ENTRY(start)

/* Define t(he sections of our binary: */
SECTIONS
{
    . = 1M;  /* All OS data start 1M in. */

    /* Set the boot section: */
    .boot :
    {
        KEEP(*(.multiboot_header))  /* Include the multiboot header. */
    }

    /* Set the text section: */
    .text :
    {
        *(.text)  /* Include the text section (CPU instructions). */
    }
}

Re: GRUB - no multiheader found

Posted: Tue Jun 29, 2021 6:08 pm
by klange
Your cmake build script is of little use here. What does your linker script look like? What does your code for the Multiboot header look like?

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 2:55 am
by Ovid
klange wrote:Your cmake build script is of little use here. What does your linker script look like? What does your code for the Multiboot header look like?
Here, I've updated the question.

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 4:42 am
by iansjack
The error messages seem to indicate that GRUB cannot find your kernel file. Set a timeout in the GRUB configuration file and you can then interrupt the boot process, examine which GRUB commands are being run, and try running them manually. This should give you some clues as to where the problem lies.

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 4:56 am
by Ovid
iansjack wrote:The error messages seem to indicate that GRUB cannot find your kernel file. Set a timeout in the GRUB configuration file and you can then interrupt the boot process, examine which GRUB commands are being run, and try running them manually. This should give you some clues as to where the problem lies.
How do I check what commands grub runs?

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 5:06 am
by Ovid
Ovid wrote:
iansjack wrote:The error messages seem to indicate that GRUB cannot find your kernel file. Set a timeout in the GRUB configuration file and you can then interrupt the boot process, examine which GRUB commands are being run, and try running them manually. This should give you some clues as to where the problem lies.
How do I check what commands grub runs?
OK, I edited the commands using the 'e' key and it seems that the .iso file didn't get the /boot folder.

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 6:35 am
by Ovid
How can I add my '/boot' folder into the bootloader?

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 6:37 am
by iansjack
Does the directory targets/x86_64/iso/boot/ exist before the cp command? And do you have the correct permissions to create files in it?

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 6:49 am
by Ovid
iansjack wrote:Does the directory targets/x86_64/iso/boot/ exist before the cp command? And do you have the correct permissions to create files in it?
This folder exists before the cp command. I have this permission because I'm using docker to compile my files.
Here is the Dockerfile content:

Code: Select all

# Install the gcc cross-compiler:
FROM randomdude/gcc-cross-x86_64-elf

# Install additional apps:
RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y nasm
RUN apt-get install -y xorriso
RUN apt-get install -y grub-pc-bin
RUN apt-get install -y grub-common
RUN apt-get update && apt-get -y install cmake protobuf-compiler

# Set the work directory:
WORKDIR /root/env

Re: GRUB - no multiheader found

Posted: Wed Jun 30, 2021 8:38 am
by iansjack
Could you explain why you include "/usr/lib/grub/i386-pc" in the grub-mkrescue command? I'm more familiar with just using

grub-mkrescue -o <ISONAME> <FOLDER_CONTAINING_OS_FILES>

Re: GRUB - no multiheader found

Posted: Thu Jul 01, 2021 2:27 pm
by Ovid
iansjack wrote:Could you explain why you include "/usr/lib/grub/i386-pc" in the grub-mkrescue command? I'm more familiar with just using

grub-mkrescue -o <ISONAME> <FOLDER_CONTAINING_OS_FILES>
I don't know why it's here. I wrote that according to a tutorial that I saw.

Re: GRUB - no multiheader found

Posted: Thu Jul 01, 2021 2:33 pm
by Ovid
iansjack wrote:Could you explain why you include "/usr/lib/grub/i386-pc" in the grub-mkrescue command? I'm more familiar with just using

grub-mkrescue -o <ISONAME> <FOLDER_CONTAINING_OS_FILES>
I run the command as you said and it still gives me the same errors when booting up the OS.

Re: GRUB - no multiheader found

Posted: Thu Jul 01, 2021 4:34 pm
by klange
iansjack wrote:The error messages seem to indicate that GRUB cannot find your kernel file.
This is incorrect. The error indicates GRUB found the file but was unable to locate the multiboot header within it.

@Ovid: Please post the output of

Code: Select all

readelf -a kernel.bin

Re: GRUB - no multiheader found

Posted: Fri Jul 02, 2021 2:14 am
by Ovid
klange wrote:
iansjack wrote:The error messages seem to indicate that GRUB cannot find your kernel file.
This is incorrect. The error indicates GRUB found the file but was unable to locate the multiboot header within it.

@Ovid: Please post the output of

Code: Select all

readelf -a kernel.bin
Hey @klange, here is the output of what you asked for:

Code: Select all

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x100000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          1052720 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         1
  Size of section headers:           64 (bytes)
  Number of section headers:         9
  Section header string table index: 8

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000100000  00100000
       00000000000004e2  0000000000000000  AX       0     0     16
  [ 2] .rodata           PROGBITS         00000000001004e8  001004e8
       0000000000000088  0000000000000000   A       0     0     8
  [ 3] .eh_frame         PROGBITS         0000000000100570  00100570
       0000000000000158  0000000000000000   A       0     0     8
  [ 4] .bss              NOBITS           00000000001006e0  001006c8
       0000000000007020  0000000000000000  WA       0     0     32
  [ 5] .comment          PROGBITS         0000000000000000  001006c8
       0000000000000011  0000000000000001  MS       0     0     1
  [ 6] .symtab           SYMTAB           0000000000000000  001006e0
       00000000000005e8  0000000000000018           7    50     8
  [ 7] .strtab           STRTAB           0000000000000000  00100cc8
       0000000000000323  0000000000000000           0     0     1
  [ 8] .shstrtab         STRTAB           0000000000000000  00100feb
       0000000000000041  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x00000000001006c8 0x0000000000107700  RWE    0x200000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata .eh_frame .bss 

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 63 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000100000     0 SECTION LOCAL  DEFAULT    1 
     2: 00000000001004e8     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000100570     0 SECTION LOCAL  DEFAULT    3 
     4: 00000000001006e0     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /root/env/src/impl/x86_64
     7: 00000000000b8000     0 NOTYPE  LOCAL  DEFAULT  ABS VIDEO_ADDR
     8: 000000002f4b2f4f     0 NOTYPE  LOCAL  DEFAULT  ABS OK_TEXT
     9: 0000000000001000     0 NOTYPE  LOCAL  DEFAULT  ABS ALIGNMENT_MEMORY
    10: 0000000000004000     0 NOTYPE  LOCAL  DEFAULT  ABS STACK_MEMORY
    11: 0000000036d76289     0 NOTYPE  LOCAL  DEFAULT  ABS BOOTLOADER_MAGIC_NUMBER
    12: 000000004f524f45     0 NOTYPE  LOCAL  DEFAULT  ABS ERROR_PRINT_VALUE_1
    13: 000000004f3a4f52     0 NOTYPE  LOCAL  DEFAULT  ABS ERROR_PRINT_VALUE_2
    14: 000000004f204f20     0 NOTYPE  LOCAL  DEFAULT  ABS ERROR_PRINT_VALUE_3
    15: 0000000080000000     0 NOTYPE  LOCAL  DEFAULT  ABS MAGIC_CHECK_VALUE_1
    16: 0000000080000001     0 NOTYPE  LOCAL  DEFAULT  ABS MAGIC_CHECK_VALUE_2
    17: 0000000000000b11     0 NOTYPE  LOCAL  DEFAULT  ABS PW_CODE
    18: 0000000000000083     0 NOTYPE  LOCAL  DEFAULT  ABS PWH_CODE
    19: 0000000000000200     0 NOTYPE  LOCAL  DEFAULT  ABS MAPPED_VALUE
    20: 0000000000200000     0 NOTYPE  LOCAL  DEFAULT  ABS TWO_MB
    21: 00000000c0000080     0 NOTYPE  LOCAL  DEFAULT  ABS ENABLE_LONG_MODE
    22: 000000000010002d     0 NOTYPE  LOCAL  DEFAULT    1 check_multiboot
    23: 0000000000100035     0 NOTYPE  LOCAL  DEFAULT    1 check_multiboot.no_multib
    24: 000000000010003c     0 NOTYPE  LOCAL  DEFAULT    1 check_cpuid
    25: 0000000000100050     0 NOTYPE  LOCAL  DEFAULT    1 check_cpuid.no_cpuid
    26: 0000000000100057     0 NOTYPE  LOCAL  DEFAULT    1 check_long_mode
    27: 0000000000100075     0 NOTYPE  LOCAL  DEFAULT    1 check_long_mode.no_long_m
    28: 0000000000100079     0 NOTYPE  LOCAL  DEFAULT    1 setup_page_tables
    29: 000000000010009c     0 NOTYPE  LOCAL  DEFAULT    1 setup_page_tables.loop_me
    30: 00000000001000b9     0 NOTYPE  LOCAL  DEFAULT    1 enable_paging
    31: 00000000001000e4     0 NOTYPE  LOCAL  DEFAULT    1 error
    32: 00000000001006e0     0 NOTYPE  LOCAL  DEFAULT    4 page_table_l4
    33: 00000000001016e0     0 NOTYPE  LOCAL  DEFAULT    4 page_table_l3
    34: 00000000001026e0     0 NOTYPE  LOCAL  DEFAULT    4 page_table_l2
    35: 00000000001036e0     0 NOTYPE  LOCAL  DEFAULT    4 stack_bottom
    36: 00000000001076e0     0 NOTYPE  LOCAL  DEFAULT    4 stack_top
    37: 00000000001004e8     0 NOTYPE  LOCAL  DEFAULT    2 gdt64
    38: 0000000000000008     0 NOTYPE  LOCAL  DEFAULT  ABS gdt64.code_segment
    39: 00000000001004f8     0 NOTYPE  LOCAL  DEFAULT    2 gdt64.pointer
    40: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /root/env/src/impl/x86_64
    41: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c
    42: 0000000000100508     8 OBJECT  LOCAL  DEFAULT    2 NUM_COLS
    43: 0000000000100510     8 OBJECT  LOCAL  DEFAULT    2 NUM_ROWS
    44: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS print.c
    45: 0000000000100550     8 OBJECT  LOCAL  DEFAULT    2 NUM_COLS
    46: 0000000000100558     8 OBJECT  LOCAL  DEFAULT    2 NUM_ROWS
    47: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS terminal.c
    48: 0000000000100560     8 OBJECT  LOCAL  DEFAULT    2 NUM_COLS
    49: 0000000000100568     8 OBJECT  LOCAL  DEFAULT    2 NUM_ROWS
    50: 0000000000100312   133 FUNC    GLOBAL DEFAULT    1 print_char
    51: 0000000000100228   234 FUNC    GLOBAL DEFAULT    1 print_newline
    52: 00000000001001ef    57 FUNC    GLOBAL DEFAULT    1 print_clear
    53: 0000000000100415    51 FUNC    GLOBAL DEFAULT    1 set_system_terminal
    54: 0000000000100124   104 FUNC    GLOBAL DEFAULT    1 kernel_main
    55: 0000000000100448    93 FUNC    GLOBAL DEFAULT    1 create_terminal
    56: 000000000010018c    99 FUNC    GLOBAL DEFAULT    1 clear_row
    57: 00000000001003ed    40 FUNC    GLOBAL DEFAULT    1 print_set_color
    58: 0000000000100397    86 FUNC    GLOBAL DEFAULT    1 print_string
    59: 0000000000100110     0 NOTYPE  GLOBAL DEFAULT    1 long_mode_start
    60: 0000000000100000     0 NOTYPE  GLOBAL DEFAULT    1 start
    61: 00000000001004a5    61 FUNC    GLOBAL DEFAULT    1 init_terminal
    62: 00000000001076e0    32 OBJECT  GLOBAL DEFAULT    4 system_terminal

No version information found in this file.

Re: GRUB - no multiheader found

Posted: Fri Jul 02, 2021 3:52 am
by klange
The Multiboot2 header needs to be within the first 0x8000 bytes of the file, but ld's gone and put all the important parts of your binary after 0x10000 for padding and alignment reasons. From the "-n" in your ld command line it looks like you're at least trying to tell it not to do that, but I'm not sure the 'nmagic' flag actually works - the usual recommendation is something like "-z max-page-size=0x1000".