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
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
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".