#gcc #сборка #os #osdev #ld
Я пытался написать примитивную ОС по урокам "Bare Bones" на osdev wiki. Проблема заключается в том, что даже на самом начале ld выдает ошибку, что главная функция ядра, _kmain, не определена. Итак, вот код: kernel.cpp void _kmain() { return; } boot.asm ; This file is loaded by GRUB, Protected Mode is already enabled ; Multiboot constants MBALIGN equ 1<<0 MEMINFO equ 1<<1 FLAGS equ MBALIGN | MEMINFO MAGIC equ 0x1BADB002 CHECKSUM equ -(MAGIC+FLAGS) ; Multiboot header section .multiboot align 4 ; Yes, I know, it's not necessary dd MAGIC dd FLAGS dd CHECKSUM ; Bootloader stack (we'll use another stack for OS, of course) section .bootstrap_stack, nobits align 4 stack_bottom: resb 16384 ; 16K of stack, seems enough for a bootloader stack_top: section .text global _start _start: mov esp, stack_top ; Stack grows in a backwards direction extern _kmain call _kmain cli ; If _kmain returns, we will halt the computer .halt: hlt jmp .halt Makefile ASM=nasm ASM_FLAGS=-felf32 CC=/home/alexander/opt/cross/bin/i686-elf-g++ CFLAGS=-ffreestanding -Wall -Wextra LINKER=/home/alexander/opt/cross/bin/i686-elf-gcc LFLAGS=-ffreestanding -nostdlib -lgcc -T linker.ld all: boot.o kernel.o $(LINKER) $(LFLAGS) -o kernel.bin $^ boot.o: $(ASM) $(ASM_FLAGS) boot.asm -o boot.o kernel.o: $(CC) $(CFLAGS) -c kernel.cpp -o kernel.o screen.o: $(CC) $(CFLAGS) -c screen.cpp -o screen.o clean: rm *.o rmbaks: rm *~ linker.ld ENTRY(_start) SECTIONS { . = 1M; .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) *(.text) } .rdata BLOCK(4K) : ALIGN(4K) { *(.rdata) } .data BLOCK(4K) : ALIGN(4K) { *(.data) } .bss BLOCK(4K) : ALIGN(4K) { *(COMMON) *(.bss) *(.bootstrap_stack) } } Вывод после запуска make: nasm -felf32 boot.asm -o boot.o /home/alexander/opt/cross/bin/i686-elf-g++ -ffreestanding -Wall -Wextra -c kernel.cpp -o kernel.o /home/alexander/opt/cross/bin/i686-elf-gcc -ffreestanding -nostdlib -lgcc -T linker.ld -o kernel.bin boot.o kernel.o boot.o: In function `_start': boot.asm:(.text+0x6): undefined reference to `_kmain' collect2: error: ld returned 1 exit status make: *** [all] Ошибка 1 P.S. В screen.cpp всякие полезные функции для работы с дисплеем, но он не используется.
Ответы
Ответ 1
На самом деле все просто упирается в компилятор. У Вас g++ (а не gcc). По умолчанию g++ формирует имена функций (те, что мы можем увидеть командой nm kernel.o) с учетом типа функции и параметров. Так, вместо ожидаемого _kmain, в .o получается _Z6_kmainv. Если Вы все еще хотите продолжать упражнения с С++, то придется явно сказать компилятору, что нужны имена функций в "сишном стиле". Для этого достаточно написать прототипы функций в специальном блоке: extern "C" { void _kmain(void); // это наш случай }; Если хотите, чтобы код без изменений (конечно, остальные его части тоже должны быть совместимы как с Си, так и с C++) компилировался также и gcc, то придется добавить немного директив препроцессора (к счастью он одинаков для g++/gcc) #ifdef __cplusplus extern "C" { #endif void _kmain(void); ... #ifdef __cplusplus }; #endif
Комментариев нет:
Отправить комментарий