我正在学习操作系统教程。 我创建了2个文件。

  1. boot.asm
  2. kernel.c

kernel.c如下:

int main()
{
  char *src = (char *)0xB8000000L;
  *src = 'M';
  src += 2;
  *src = 'D';
  return 0;
}

内核用于将字符写入文本模式视频显示区域。 使用Windows版本的GCC编译内核:

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

===============>>#1 票数:4 已采纳

您的Windows版本的LD可能不支持除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

===============>>#2 票数:1

这意味着ld本身在编译时未配置为支持除PE之外的输出格式, Portable Executable - 本机Windows可执行文件格式。

找一个支持或自己构建它的人。

  ask by Panther Coder translate from so

未解决问题?本站智能推荐:

1回复

在不使用C库的情况下在0xb8000处显示文本视频内存

我一直在用C编写内核。我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标。 我没有可用于编写内核的C库。 我已经开始使用一些代码来假设将字符直接打印到屏幕上。 这是kernel.c一个函数: 我使用GCC使用参数-m16编译了我的代码,以生成将以实模式运
1回复

Qemu和原始二进制文件

我正在编译并运行二进制文件(引导扇区,第1阶段,第2阶段)进行练习。 引导扇区是asm,第一个阶段是asm运行正常。 第二阶段加载到0x1000,我有一些asm跳转到我的C代码的开头。 我的跳转和调用似乎关闭(短)两个字节。 我已经尝试过Bochs和Qemu中的代码(单步执行)。
1回复

将16位实模式代码链接到符合Multiboot的ELF可执行文件时出现LD错误

我正在编写一个包含我的32位内核的Multiboot兼容的ELF可执行文件。 我的主要问题是我在生成可执行文件时收到一系列链接器错误: 重定位被截断以适合:R_386_16对``.text' 链接器脚本,代码和构建脚本如下 我决定尝试在我的操作系统中实现VESA VBE
2回复

使用16位模式在没有BIOS例程的情况下打印字母

我意识到在保护模式下,可以通过修改内存位置0xb8000等来使用内存映射的I / O来打印字母...我们可以在16位实模式下执行此操作吗? (使用细分访问位置,然后对其进行修改) 这是我的汇编代码... 顺便说一句,这是行不通的。 [edit]事实证明,我最后需要jmp $
3回复

如何使用汇编语言修复“ os.asm:113:错误:TIMES值-138为负”

我正在使用汇编语言开发操作系统。 在某个时候,我从NASM收到此错误: os.asm:113:错误:TIMES值-138为负 我想结束这个项目。 只有这样的错误使我感到绝望! 这是代码: 为什么Times值是负数? 为什么其他人没有得到相同的错误? (或者
1回复

使用int13h从软盘加载段

我目前正在尝试编写16位实模式启动代码来打印一个字母,然后从软盘加载第二段并跳转到它,然后还打印一个字母。 但是,我对Read Sectors From Drive调用的工作方式感到有些困惑。 到目前为止,这是我的代码: 第二个汇编程序文件,我复制到软盘的第二个扇区,看起来像这样
1回复

在组装/编译/链接时构建静态IDT和GDT所需的解决方案

多年来,尤其是在x86操作系统开发中遇到的许多问题都激发了这个问题。 最近, 有关NASM的一个问题因修改而引起争议 。 在那种情况下,该人正在使用NASM并遇到汇编时间错误: 移位运算符只能应用于标量值 另一个相关问题是在编译时生成静态IDT时导致错误的GCC代码问题:
2回复

玩具OS文件系统[关闭]

我在assembly / c中开发了一个运行基本终端的基本内核。 我把它设置为用grub运行iso。 我想继续这个操作系统,但没有文件系统,我觉得我真的没有别的办法。 经过很长一段时间在互联网上,我已经想出了实现这一点我真的无能为力。 人们已经说过实现FAT或制作VFS,但没有任
2回复

nasm / ld“重定位被截断以适合:R_386_16”

部件: 组装与: 然后将其与: 给出以下错误: 稍微摆弄代码后,我发现将mov si, hw更改为mov si, 0x100可以正常工作。 但是标签的意义是什么? 我的猜测是ld无法生成16位二进制文​​件,因此它用32位地址而不是16位地址替换了hw 。
1回复

Kernel.c无法执行完整的代码[从头开始使用操作系统]

我是操作系统的初学者,我正在尝试从头开始构建os(在本教程之后 )。 虽然我可以执行作者提供的代码。 但是,当我添加我的自定义引导程序(显然会占用更多内存,并等待键盘中断来加载内核),然后尝试按照本教程中的说明添加驱动程序时,我的内核不会执行完整的代码(可能是,也可能不是)。 实际上,