Связывание файла с помощью ld для вывода двоичного файла приводит к ошибке в разработке ОС
Я изучаю учебники по операционной системе. Я создал 2 файла.
- boot.asm
- 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.
Найдите тот, который поддерживает, или постройте его самостоятельно.