加载内核时,GRUB2产生“找不到多重引导头”错误

问题描述

我读了GRUB Multiboot header not found,但仍然无法加载内核

我试图直接在.s文件中写入multiboot2标头,然后将其链接。它应该出现在所有其他段之前:

[kheader.s]

.section .mbt2std
tag_start:
.long 0xE85250D6
.long 0
.long tag_end-tag_start
.long -1*(tag_end-tag_start + 0 +  0xE85250D6)
.short 0
.short 0
.short 8
tag_end:

[链接脚本]

OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(kmain)
SECTIONS
{
    . = 1M;
    .text ALIGN(4K):
    {
        *(.mbt2std)
        *(.text)
    }
    .rodata :
    {
        *(.data)
    }
    .data :
    {
        *(.data)
    }
    .bss :
    {
        *(.bss)
    }
}

[转储]

alan@alan-virtual-machine:~/git/Lithium-OS/src$ make dmp
objdump -s ../build/lithium.elf

../build/lithium.elf:     文件格式 elf64-x86-64

Contents of section .text:
 100000 d65052e8 00000000 16000000 14afad17  .PR.............
 100010 00000000 08005548 89e54883 ec104889  ......UH..H...H.
 100020 7df89048 8b45f848 83c0070f b6000fb6  }..H.E.H........
 100030 c089c748 b8b00510 00000000 00ffd0c0  ...H............

symbol table '.symtab' contains 36 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000100000     0 SECTION LOCAL  DEFAULT    1 
     2: 0000000000100b50     0 SECTION LOCAL  DEFAULT    2 
     3: 0000000000100e20     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS ../build/kheader.o
     5: 0000000000100000     0 NOTYPE  LOCAL  DEFAULT    1 tag_start
     6: 0000000000100016     0 NOTYPE  LOCAL  DEFAULT    1 tag_end
     7: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS ata.c
     8: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS ioport.c
     9: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS kernel.c
    10: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS sysop.c
    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS univideo.c
    12: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS vbe.c
    13: 00000000001005ce    29 FUNC    GLOBAL DEFAULT    1 out_port16

    alan@alan-virtual-machine:~/git/Lithium-OS/src$ hexdump ../build/lithium.elf 
    0000000 457f 464c 0102 0001 0000 0000 0000 0000
    0000010 0002 003e 0001 0000 0606 0010 0000 0000
    0000020 0040 0000 0000 0000 1058 0010 0000 0000
    0000030 0000 0000 0040 0038 0002 0040 0007 0004
    0000040 0001 0000 0007 0000 0000 0000 0000 0000
    0000050 0000 0000 0000 0000 0000 0000 0000 0000
    0000060 0b62 0010 0000 0000 0e48 0010 0000 0000
    0000070 0000 0020 0000 0000 e551 6474 0007 0000
    0000080 0000 0000 0000 0000 0000 0000 0000 0000
    *
    00000a0 0000 0000 0000 0000 0008 0000 0000 0000
    00000b0 0000 0000 0000 0000 0000 0000 0000 0000
    *
    0100000 50d6 e852 0000 0000 0016 0000 af14 17ad //1MiB
    0100010 0000 0000 0008 4855 e589 8348 10ec 8948
    0100020 f87d 4890 458b 48f8 c083 0f07 00b6 b60f
    0100030 89c0 48c7 b0b8 1005 0000 0000 ff00 c0d0
    0100040 06e8 013c dd74 c990 55c3 8948 48e5 ec83
    0100050 4830 7d89 48e8 7589 48e0 5589 48d8 ffb8
    0100060 ffff ffff 00ff 4800 4539 76e0 480c c0c7
    0100070 ffff ffff 6fe9 0002 4800 458b 48e8 c789
    0100080 b848 0016 0010 0000 0000 d0ff 8b48 e845
    0100090 8348 01c0 b60f 0f00 c0b6 00be 0000 8900
    01000a0 48c7 ebb8 1005 0000 0000 ff00 48d0 458b

通过hexdump,您可以看到他被准确地放置在1M地址,因此Grub无法识别它。如何将标题放置在文件的前端?

这是制作日志

alan@alan-virtual-machine:~/git/Lithium-OS/src$ make
make clean
make[1]: Entering directory '/home/alan/git/Lithium-OS/src'
rm -rf ../build/
mkdir ../build/
make[1]: Leaving directory '/home/alan/git/Lithium-OS/src'
time make all
make[1]: Entering directory '/home/alan/git/Lithium-OS/src'
[II] Making Libs
make -C ./lib libs
make[2]: Entering directory '/home/alan/git/Lithium-OS/src/lib'
[II] Making IO Lib
make -C ./io lib-io
make[3]: Entering directory '/home/alan/git/Lithium-OS/src/lib/io'
gcc -mcmodel=large -fno-builtin -I ../include -m64 -c -Wall -nostdinc -nostdlib ioport.c -o ../../../build/ioport.o 2>>../../../build/cmplog >>../../../build/cmplog
gcc -mcmodel=large -fno-builtin -I ../include -m64 -c -Wall -nostdinc -nostdlib ata.c -o ../../../build/ata.o 2>>../../../build/cmplog >>../../../build/cmplog
make[3]: Leaving directory '/home/alan/git/Lithium-OS/src/lib/io'
[II] Making SYS Lib
make -C ./sys lib-sys
make[3]: Entering directory '/home/alan/git/Lithium-OS/src/lib/sys'
gcc -mcmodel=large -fno-builtin -I ../include -m64 -c -Wall -nostdinc -nostdlib sysop.c -o ../../../build/sysop.o 2>>../../../build/cmplog >>../../../build/cmplog
make[3]: Leaving directory '/home/alan/git/Lithium-OS/src/lib/sys'
[II] Making Video Lib
make -C ./video lib-video
make[3]: Entering directory '/home/alan/git/Lithium-OS/src/lib/video'
gcc -mcmodel=large -fno-builtin -I ../include -m64 -c -Wall -nostdinc -nostdlib vbe.c -o ../../../build/vbe.o 2>>../../../build/cmplog >>../../../build/cmplog
gcc -mcmodel=large -fno-builtin -I ../include -m64 -c -Wall -nostdinc -nostdlib univideo.c -o ../../../build/univideo.o 2>>../../../build/cmplog >>../../../build/cmplog
make[3]: Leaving directory '/home/alan/git/Lithium-OS/src/lib/video'
[II] All Libs Ok
make[2]: Leaving directory '/home/alan/git/Lithium-OS/src/lib'
[II] Making KernelHeader
as --64 -o ../build/kheader.o kheader.s
[II] Header is OK
[II] Making Kernel
gcc -mcmodel=large -fno-builtin -I ./lib/include -m64 -c -Wall -nostdinc -nostdlib kernel.c -o ../build/kernel.o 2>>../build/cmplog >>../build/cmplog
[II] EveryLib is Ok,Start Linking
[II] Linking
ld -T kernel.lds --build-id=none -b elf64-x86-64 -o ../build/lithium~dirty.o ../build/*.o
[II] Cleaning Other Section
objcopy -R ".eh_frame" -R ".comment" ../build/lithium~dirty.o ../build/lithium.elf
make[1]: Leaving directory '/home/alan/git/Lithium-OS/src'
0.26user 0.23system 0:00.51elapsed 96%CPU (0avgtext+0avgdata 18220maxresident)k
0inputs+176outputs (0major+21075minor)pagefaults 0swaps
[II] Compile Complete.
[II] Kernel:../build/lithium.elf

ls -l ../build/lithium.elf
-rwxrwxr-x 1 alan alan 1053208 10月 24 14:18 ../build/lithium.elf

objdump -f ../build/lithium.elf

../build/lithium.elf:     文件格式 elf64-x86-64
体系结构:i386:x86-64, 标志 0x00000112:
EXEC_P,HAS_SYMS,D_PAGED
起始地址 0x0000000000100606

[II] Checking Vaild MB2
make chkmb
make[1]: Entering directory '/home/alan/git/Lithium-OS/src'
grub-file --is-x86-multiboot2  ../build/lithium.elf
Makefile:59: recipe for target 'chkmb' failed
make[1]: *** [chkmb] Error 1
make[1]: Leaving directory '/home/alan/git/Lithium-OS/src'
Makefile:26: recipe for target 'system' failed
make: *** [system] Error 2

解决方法

看着hexdump,Multiboot2标头是文件中的1MiB,这就是为什么它找不到它的原因。 Multiboot2标头必须位于first 32KiB of the ELF executable and be 64-bit aligned中。因为代码是由64位编译器生成的,所以这些节可能是2MiB页面对齐的。您将需要将其更改为4KiB对齐,以确保可以找到Multiboot标头。

将链接命令行修改为:

ld -z max-page-size = 0x1000 -T kernel.lds --build-id = none -b elf64-x86-64 -o ../build/lithium~dirty.o ../build/*.o。

选项-z max-page-size=0x1000将最大页面对齐方式修改为0x1000(4096或4KiB)而不是2MiB。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...