微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

链接器找不到外部引用

如何解决链接器找不到外部引用

我正在关注OS Dev Wiki's Bare Bones tutorial。但是,当我尝试将所有内容链接在一起时,我的链接器(Cygwin Binutils)给了我以下错误

boot.o: In function `start':
boot.asm:(.text+0x6): undefined reference to `kernmain'

当我运行命令时

i686-pc-cygwin-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib kernel.o boot.o -lgcc

以前,我认为 kernel_main() 中入口点的标识符 (kernel.c) 与其他一些重要命名空间(每个 this other somewhat similary answer which I've already tried and didn't work)具有相同的标识符。

---编辑--- 这是源代码,尽管您可以使用 wiki 页面上的内容重现所有内容

boot.asm

MBALIGN equ 1 << 0
MEMINFO equ 1 << 0
FLAGS equ MBALIGN | MEMINFO
MAGIC equ 0x1BADB002                ;magic number tells cpu where to find the bootloader
CHECKSUM equ -(MAGIC + FLAGS)       ;checksum of above

section .multiboot
    dd MAGIC
    dd FLAGS
    dd CHECKSUM

section .bss
align 16
stack_bottom:
resb 16384 ;16 kilobytes
stack_top:

section .text
global _start:function (_start.end - _start)
_start:
    mov esp,stack_top

    [extern kernmain]
    call kernmain

    cli

.hang: hlt
    jmp .hang

.end:

内核.c

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

enum vga_color
{
    BLACK = 0,BLUE = 1,GREEN = 2,CYAN = 3,RED = 4,magenta = 5,broWN = 6,LIGHT_GREY = 7,DARK_GREY = 8,LIGHT_BLUE = 9,LIGHT_GREEN = 10,LIGHT_CYAN = 11,LIGHT_RED = 12,LIGHT_magenta = 13,LIGHT_broWN = 14,WHITE = 15
};

static inline uint8_t vga_entry_color(enum vga_color foreground,enum vga_color background)
{
    return foreground | background << 4;
}

static inline uint16_t vga_entry(unsigned char c,uint8_t color)
{
    return (uint16_t)c | (uint16_t)color << 8;
}

size_t strlen(const char* str)
{
    size_t len = 0;
    while (str[len])
    {
        len++;
    }
    return len;
}

static const size_t VGA_WIDTH = 80;
static const size_t VGA_HEIGHT = 25;

size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer;

void terminal_initialize()
{
    terminal_row = 0;
    terminal_column = 0;
    terminal_color = vga_entry_color(WHITE,BLACK);
    terminal_buffer = (uint16_t*)0xB8000;
    for (size_t y = 0; y < VGA_HEIGHT; y++) {
        for (size_t x = 0; x < VGA_WIDTH; x++) {
            const size_t index = y * VGA_WIDTH + x;
            terminal_buffer[index] = vga_entry(' ',terminal_color);
        }
    }
}

void terminal_setcolor(uint8_t color)
{
    terminal_color = color;
}

void terminal_putentryat(char c,uint8_t color,size_t x,size_t y)
{
    const size_t index = y * VGA_WIDTH + x;
    terminal_buffer[index] = vga_entry(c,color);
}

void terminal_putchar(char c)
{
    terminal_putentryat(c,terminal_color,terminal_column,terminal_row);
    if (++terminal_column == VGA_WIDTH) {
        terminal_column = 0;
        if (++terminal_row == VGA_HEIGHT)
            terminal_row = 0;
    }
}

void terminal_write(const char* data,size_t size)
{
    for (size_t i = 0; i < size; i++)
        if (data[i] == '\n')
        {
            terminal_row++;
        }
        else if (data[i] == '\r')
        {
            terminal_column = 0;
        }
        else 
        {
            terminal_putchar(data[i]);
        }
}

void terminal_writestring(const char* data)
{
    terminal_write(data,strlen(data));
}

void kernmain(void)
{
    terminal_initialize();

    terminal_writestring("Hello,kernel World!\nHere again");
}

链接器.ld

ENTRY(_start)

SECTIONS
{
    . = 1M;

    .text BLOCK(4K) : ALIGN(4K)
    {
        *(.multiboot)
        *(.text)
    }

    .rodata BLOCK(4K) : ALIGN(4K)
    {
        *(.rodata)
    }

    .data BLOCK(4K) : ALIGN(4K)
    {
        *(.data)
    }

    .bss BLOCK(4K) : ALIGN(4K)
    {
        *(COMMON)
        *(.bss)
    }
}

这是我运行的命令来构建它

nasm -f elf32 boot.asm -o boot.o
i686-pc-cygwin-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
i686-pc-cygwin-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib kernel.o boot.o -lgcc

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。