当遵循简单的内核教程时,会出现奇怪的链接器错误

时间:2022-09-06 14:17:32

Im following this tutorial on how to make a simple bootable kernel: http://www.osdever.net/tutorials/view/writing-a-simple-c-kernel

我正在学习如何制作一个简单的可引导内核:http://www.osdever.net/tutorials/view/writing- simple-c-kernel。

there are the following required files in the tutorial:

本教程中有以下所需文件:

kernel.c source code:

内核。c源代码:

#define WHITE_TXT 0x07 // white on black text

void k_clear_screen();
unsigned int k_printf(char *message, unsigned int line);


k_main() // like main in a normal C program
{
    k_clear_screen();
    k_printf("Hi!\nHow's this for a starter OS?", 0);
};

void k_clear_screen() // clear the entire text screen
{
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;
    while(i < (80*25*2))
    {
        vidmem[i]=' ';
        i++;
        vidmem[i]=WHITE_TXT;
        i++;
    };
};

unsigned int k_printf(char *message, unsigned int line) // the message and then the line #
{
    char *vidmem = (char *) 0xb8000;
    unsigned int i=0;

    i=(line*80*2);

    while(*message!=0)
    {
        if(*message=='\n') // check for a new line
        {
            line++;
            i=(line*80*2);
            *message++;
        } else {
            vidmem[i]=*message;
            *message++;
            i++;
            vidmem[i]=WHITE_TXT;
            i++;
        };
    };

    return(1);
};

kernel_start.asm source code:

kernel_start。asm源代码:

[BITS 32]

[global start]
[extern _k_main] ; this is in the c file

start:
  call _k_main

  cli  ; stop interrupts
  hlt ; halt the CPU

link.ld source code:

链接。ld源代码:

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
  .text  0x100000 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }
  .data  : {
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss  :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .; _end = .; __end = .;
}

The instructions to compile it are:

编写指南如下:

nasm -f aout kernel_start.asm -o ks.o
gcc -c kernel.c -o kernel.o
ld -T link.ld -o kernel.bin ks.o kernel.o

i am able to successfully execute the first two lines:

我能够成功地执行前两行:

nasm -f aout kernel_start.asm -o ks.o
gcc -c kernel.c -o kernel.o

then when i try and run this line :

然后当我试着运行这条线:

ld -T link.ld -o kernel.bin ks.o kernel.o

I get the error:

我得到了错误:

C:\basic_kernel>ld -T link.ld -o kernel.bin ks.o kernel.o
ks.o: file not recognized: File format not recognized

Does anyone know why this is and how I could fix this? I'm using windows 7 64 bit

有人知道这是为什么吗?我使用的是windows 7 64位

3 个解决方案

#1


2  

NASM defaults to flat binary mode when not given a format with the -f option. You need to change -f aout to -f elf in order to link the produced object file

如果没有使用-f选项提供格式,NASM默认为平面二进制模式。您需要将-f aout更改为-f elf,以便链接生成的对象文件

#2


0  

Your gcc and ld are probably expecting PECOFF or ELF object files, rather than a.out, which is old and obsolete. Try removing the -f aout from your nasm invocation.

您的gcc和ld可能需要PECOFF或ELF对象文件,而不是a。过时了。尝试从nasm调用中删除-f aout。

If that doesn't work, try naming this file ks.s, assembling it with gcc ks.s -c -o ks.o, and using it instead of the ks.o / kernel_start.asm you have:

如果这不起作用,请尝试命名这个文件ks。用gcc ks来组装。s - c - o ks。用它代替k。o / kernel_start。asm你有:

    .text
    .code32
    .globl start
start:
    call _k_main
    cli
    hlt

Warning: It doesn't show up in this example, but the instruction syntax used when you write assembly this way is very different from what you might be expecting. This SO question links to a guide.

警告:在本例中没有出现,但是以这种方式编写程序集时使用的指令语法与预期的非常不同。这个问题链接到一个指南。

Additional wrinkle to be aware of: there are excellent odds that you should not have an underscore at the beginning of the symbol _k_main in the assembly. Underscores at the beginning of all symbols defined in C is how it worked in a.out, but is not done in ELF. I don't know about PECOFF.

需要注意的另外一个问题是:在程序集中_k_main符号的开头不应该有下划线的可能性非常大。在C中定义的所有符号的开头的下划线是它在a中的工作方式。退出,但不是在精灵。我不知道什么叫PECOFF。

#3


0  

I don't use windows so I do not know how this would apply to your problem, but I once had the same issue while compiling my kernel (ld gave me the same error code). The problem was that my code was being compiled by clang instead of being compiled by my toolchain's GCC, so therefore when my toolchain's ld tried to link it, it couldn't read the object files because they weren't in the format it was expecting. If you are not using an x86 toolchain (cross-compiler) use one and make sure you are using the GCC included in that toolchain to compile your files.

我不使用windows,所以我不知道这将如何应用于您的问题,但是我在编译内核时遇到了同样的问题(ld给了我相同的错误代码)。问题是我的代码是由clang编译的,而不是由我的工具链的GCC编译的,因此当我的工具链的ld试图链接它时,它无法读取对象文件,因为它们不是它期望的格式。如果您不使用x86工具链(交叉编译器),请使用它,并确保您正在使用工具链中包含的GCC来编译文件。

#1


2  

NASM defaults to flat binary mode when not given a format with the -f option. You need to change -f aout to -f elf in order to link the produced object file

如果没有使用-f选项提供格式,NASM默认为平面二进制模式。您需要将-f aout更改为-f elf,以便链接生成的对象文件

#2


0  

Your gcc and ld are probably expecting PECOFF or ELF object files, rather than a.out, which is old and obsolete. Try removing the -f aout from your nasm invocation.

您的gcc和ld可能需要PECOFF或ELF对象文件,而不是a。过时了。尝试从nasm调用中删除-f aout。

If that doesn't work, try naming this file ks.s, assembling it with gcc ks.s -c -o ks.o, and using it instead of the ks.o / kernel_start.asm you have:

如果这不起作用,请尝试命名这个文件ks。用gcc ks来组装。s - c - o ks。用它代替k。o / kernel_start。asm你有:

    .text
    .code32
    .globl start
start:
    call _k_main
    cli
    hlt

Warning: It doesn't show up in this example, but the instruction syntax used when you write assembly this way is very different from what you might be expecting. This SO question links to a guide.

警告:在本例中没有出现,但是以这种方式编写程序集时使用的指令语法与预期的非常不同。这个问题链接到一个指南。

Additional wrinkle to be aware of: there are excellent odds that you should not have an underscore at the beginning of the symbol _k_main in the assembly. Underscores at the beginning of all symbols defined in C is how it worked in a.out, but is not done in ELF. I don't know about PECOFF.

需要注意的另外一个问题是:在程序集中_k_main符号的开头不应该有下划线的可能性非常大。在C中定义的所有符号的开头的下划线是它在a中的工作方式。退出,但不是在精灵。我不知道什么叫PECOFF。

#3


0  

I don't use windows so I do not know how this would apply to your problem, but I once had the same issue while compiling my kernel (ld gave me the same error code). The problem was that my code was being compiled by clang instead of being compiled by my toolchain's GCC, so therefore when my toolchain's ld tried to link it, it couldn't read the object files because they weren't in the format it was expecting. If you are not using an x86 toolchain (cross-compiler) use one and make sure you are using the GCC included in that toolchain to compile your files.

我不使用windows,所以我不知道这将如何应用于您的问题,但是我在编译内核时遇到了同样的问题(ld给了我相同的错误代码)。问题是我的代码是由clang编译的,而不是由我的工具链的GCC编译的,因此当我的工具链的ld试图链接它时,它无法读取对象文件,因为它们不是它期望的格式。如果您不使用x86工具链(交叉编译器),请使用它,并确保您正在使用工具链中包含的GCC来编译文件。