无法识别的仿真模式:MinGW32 上的 elf_i386

2024-05-20

我正在尝试制作内核,但无法链接C与程序集一起输出。这ld。我收到错误:

无法识别的仿真模式:elf_i386

我正在使用 Windows 10 专业版以及 MinGW32 和 MSYS。我正在使用的代码:

link.ld

/*
*  link.ld
*/
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
 {
   . = 0x100000;
   .text : { *(.text) }
   .data : { *(.data) }
   .bss  : { *(.bss)  }
 }

kernel.c

/*
*  kernel.c
*/
void kmain(void)
{
    const char *str = "my first kernel";
    char *vidptr = (char*)0xb8000;  //video mem begins here.
    unsigned int i = 0;
    unsigned int j = 0;

    /* this loops clears the screen
    * there are 25 lines each of 80 columns; each element takes 2 bytes */
    while(j < 80 * 25 * 2) {
        /* blank character */
        vidptr[j] = ' ';
        /* attribute-byte - light grey on black screen */
        vidptr[j+1] = 0x07;         
        j = j + 2;
    }

    j = 0;

    /* this loop writes the string to video memory */
    while(str[j] != '\0') {
        /* the character's ascii */
        vidptr[i] = str[j];
        /* attribute-byte: give character black bg and light grey fg */
        vidptr[i+1] = 0x07;
        ++j;
        i = i + 2;
    }
    return;
}

内核.asm

;;kernel.asm
bits 32         ;nasm directive - 32 bit
section .text

global start
extern kmain            ;kmain is defined in the c file

start:
  cli           ;block interrupts
  mov esp, stack_space  ;set stack pointer
  call kmain
  hlt           ;halt the CPU

section .bss
resb 8192       ;8KB for stack
stack_space:

要编译和链接我使用:

nasm -f elf32 kernel.asm -o kasm.o
gcc -m32 -c kernel.c -o kc.o
ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o

我在用着:

  • 海湾合作委员会4.8.1
  • LD 2.25.1
  • 纳斯姆 2.11.09rc1

为什么我会收到此错误,如何修复它?


标准MinGW/32LD链接器不输出ELF二进制文件。您最好使用 i686 交叉编译器,但如果您不使用,您也许可以摆脱下面的提示。

看来您正在使用 Arjun 的让我们写一个内核 http://arjunsreedharan.org/post/82710718100/kernel-101-lets-write-a-kernel教程。如果您正在遵循该教程,那么您错过了一个步骤kernel.asm兼容于GRUB引导加载程序和QEMU's -kernel选项。在我们开始之前,您应该阅读本教程的其余部分。以下代码将 Multiboot 标头添加到kernel.asm使其与 GRUB 兼容:

;;kernel.asm
bits 32         ;nasm directive - 32 bit
global entry
extern _kmain            ;kmain is defined in the c file

section .text
entry:  jmp start

        ;multiboot spec
        align 4
        dd 0x1BADB002            ;magic
        dd 0x00                  ;flags
        dd -(0x1BADB002 + 0x00)  ;checksum. m+f+c should be zero

start:
        cli           ;block interrupts
        mov esp, stack_space  ;set stack pointer
        call _kmain
        hlt           ;halt the CPU

section .bss
resb 8192       ;8KB for stack
stack_space:

除了添加标题之外,我还添加了entry文件中的标签和jmp start跳过多重引导标头。我这样做是为了方便您将来开始调试时在 0x100000 处设置断点。

另一项变化是在 MinGW 上,GCC默认情况下为函数名称添加下划线。我已经更改了对C功能kmain to _kmain。这与 Linux 约定不同。

由于我们代码的入口点现在是entry代替start我已经修改了link.ld to be:

/*
*  link.ld
*/
OUTPUT_FORMAT(pei-i386)    
ENTRY(entry)

SECTIONS
 {
   . = 0x100000;
   .text : { *(.text) }
   .data : { *(.data) }
   .bss  : { *(.bss)  }
 }

上面文件中的另一个重要变化是使用OUTPUT_FORMAT(pei-i386)。这将输出一个可移植可执行映像(32 位)而不是ELF(不支持)。

为了构建内核并生成ELF图像来自PEI-I386我们可以使用这些命令:

nasm -f elf32 kernel.asm -o kasm.o
gcc -m32 -c kernel.c -o kc.o -ffreestanding -nostdlib -nostdinc
ld -T link.ld -o kernel kasm.o kc.o -build-id=none
objcopy -O elf32-i386 kernel kernel.elf

The LD命令已修改为不将 build-id 写入可执行文件,以避免多重引导标头移至可执行文件的前 8k 之外。这GCC选项已被修改为使用选项生成独立代码(没有标准库和包含)-ffreestanding -nostdlib -nostdinc。我们用objcopy来转换PEI-I386 file (kernel) to an ELF32图像称为kernel.elf。你会想要使用kernel.elf with GRUB and/or QEMU.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法识别的仿真模式:MinGW32 上的 elf_i386 的相关文章

随机推荐