Я написал голую ОС на c с загрузчиком сборок, но не могу запустить его, каждый раз, когда я запускаю его, я получаю сообщение об ошибке "не найден заголовок мультизагрузки" от grub2.Я знаю, что мой код не проблема, я пытался скомпилировать другие ОС, и они выдают ту же ошибку.Системные спецификации: Ubuntu Linux с gcc версии 7.2.Я уже рассмотрел все остальные вопросы по этому поводу, и ни один из них не помог мне.
Я использую эти команды для компиляции моей ОС:
as boot.s -o boot.o
gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
gcc -T linker.ld -o MyOS.bin -ffreestanding -O2 -nostdlib kernel.o boot.o -lgcc
grub-file --is-x86-multiboot MyOS.bin
mkdir -p isodir/boot/grub
cp MyOS.bin isodir/boot/MyOS.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o MyOS.iso isodir
qemu-system-x86_64 -cdrom MyOS.iso
bootloader:
# set magic number to 0x1BADB002 to identified by bootloader
.set MAGIC, 0x1BADB002
# set flags to 0
.set FLAGS, 0
# set the checksum
.set CHECKSUM, -(MAGIC + FLAGS)
# set multiboot enabled
.section .multiboot
# define type to long for each data defined as above
.long MAGIC
.long FLAGS
.long CHECKSUM
# set the stack bottom
stackBottom:
# define the maximum size of stack to 512 bytes
.skip 512
# set the stack top which grows from higher to lower
stackTop:
.section .text
.global _start
.type _start, @function
_start:
# assign current stack pointer location to stackTop
mov $stackTop, %esp
# call the kernel main source
call KERNEL_MAIN
cli
# put system in infinite loop
hltLoop:
hlt
jmp hltLoop
.size _start, . - _start
компоновщик:
/* The bootloader will look at this image and start execution at the symbol designated at the entry point. */
ENTRY(_start)
SECTIONS
{
/* Begin putting sections at 1 MiB, a conventional place for kernels to be
loaded at by the bootloader. */
. = 1M;
/* First put the multiboot header, as it is required to be put very early in the image or the bootloader won't recognize the file format. Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
/* Read-write data (uninitialized) and stack */
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
}
ядро:
#include"kernel.h"
static UINT16 VGA_DefaultEntry(unsigned char to_print) {
return (UINT16) to_print | (UINT16)WHITE_COLOR << 8;
}
void KERNEL_MAIN()
{
TERMINAL_BUFFER = (UINT16*) VGA_ADDRESS;
TERMINAL_BUFFER[0] = VGA_DefaultEntry('H');
TERMINAL_BUFFER[1] = VGA_DefaultEntry('e');
TERMINAL_BUFFER[2] = VGA_DefaultEntry('l');
TERMINAL_BUFFER[3] = VGA_DefaultEntry('l');
TERMINAL_BUFFER[4] = VGA_DefaultEntry('o');
TERMINAL_BUFFER[5] = VGA_DefaultEntry(' ');
TERMINAL_BUFFER[6] = VGA_DefaultEntry('W');
TERMINAL_BUFFER[7] = VGA_DefaultEntry('o');
TERMINAL_BUFFER[8] = VGA_DefaultEntry('r');
TERMINAL_BUFFER[9] = VGA_DefaultEntry('l');
TERMINAL_BUFFER[10] = VGA_DefaultEntry('d');
}