Связывание файла с помощью ld для вывода двоичного файла приводит к ошибке в разработке ОС

Я изучаю учебники по операционной системе. Я создал 2 файла.

  1. boot.asm
  2. kernel.c

Файл kernel.c выглядит следующим образом:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}

Ядро используется для записи символа в область отображения видео в текстовом режиме. Ядро было скомпилировано с использованием версии GCC для Windows с:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o

Я связываю объект ядра с двоичным файлом, используя LD:

ld -Ttext 0x10000 --oformat binary -o kernel.bin kernel.o

Я получаю ошибку:

ld: не может связать файл, который не является исполняемым типом PE

Кто-нибудь может решить эту ошибку?

  • Используемая ОС: Windows
  • компилятор: GCC
  • Линкер: ld

2 ответа

Решение

Ваша версия LD для Windows, вероятно, не поддерживает ничего, кроме типов Windows PE. Одним из способов решения этой проблемы является вывод в PE, а затем использование objcopy конвертировать из PE файла в двоичный файл

Чтобы это работало, вам придется переименовать main в _main, С -ffreestanding GCC создаст объект без соглашения Windows ABI о добавлении подчеркивания к нестатическим функциям. Сначала мы будем использовать ваш LD для вывода файла Windows PE, и он будет жаловаться на __main точка входа не определена. Чтобы обойти это вы переименовываете main в _main так что компоновщик не жалуется.

Используйте эти инструкции для генерации двоичного файла ядра:

gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin

Команда LD выводит в файл с именем kernel.pe, objcopy новообращенные kernel.pe в двоичном с -O binary вывод на kernel.bin

Это означает, что ld сам не настроен во время компиляции для поддержки форматов вывода, кроме PE, Portable Executable - родной формат исполняемого файла Windows.

Найдите тот, который поддерживает, или постройте его самостоятельно.

Другие вопросы по тегам