【问题标题】:Compiling and linking NASM and 64-bit C code together into a bootloader [duplicate]将 NASM 和 64 位 C 代码一起编译并链接到引导加载程序 [重复]
【发布时间】:2019-01-27 02:48:57
【问题描述】:

我制作了一个非常简单的 1 阶段引导加载程序,它主要做两件事:它从 16 位实模式切换到 64 位长模式,并从硬盘读取接下来的几个扇区,用于启动基本内核。

对于基本内核,我正在尝试用 C 语言而不是汇编语言编写代码,对此我有一些疑问:

  1. 我应该如何编译和链接nasm文件和C文件?
  2. 在编译文件时,我应该编译成 16 位还是 64 位?因为我正在从 16 位切换到 64 位。
  3. 如何将更多来自 C 或程序集的文件添加到项目中?

我重写了问题以使我的目标更明确,所以如果需要源代码,请告诉我添加它。

代码:https://github.com/LatKid/BasicBootloaderNASMC

【问题讨论】:

  • 由于我无法编写答案,您可以查看我为您编写的链接器脚本。我也将 stage2 与引导扇区分开(尽管它确实可以在 bootSector.asm 中删除)。有一个 build.sh 文件来展示它是如何组合在一起的,也许它会给你一些想法。这个评论部分不够我详细说明。我还将 FREE_SPACE 放置在引导加载程序下方的 0x1000 处,并且不妨碍内核。修复了一个错误,将 jnc $+3 替换为标签。要加载的扇区由链接器计算。 capp-sysware.com/misc/stackoverflow/51939790
  • 还应该指出您正在尝试做的事情(将所有文件链接在一起并具有组合的引导加载程序和内核)需要链接描述文件。如果您愿意将不同的部分分开并将它们分别放在磁盘上,您可以在没有链接描述文件的情况下做到这一点,但是很难共享符号。
  • 我已经从聊天中复制了这些 cmets,因为他们已经回答了 OPs 的问题并且他们得到了它的工作。不幸的是问题仍然关闭,我无法提供实际答案。

标签: gcc x86 nasm ld bootloader


【解决方案1】:

由于我也将 nasm 文件与 C 文件链接,它从 nasm 对象文件中吐出一个错误,即在制作共享对象时无法使用针对 .text' 的重定位 R_X86_64_16;用 -fPIC 重新编译

您的一个问题可能在 nasm 汇编程序文件中(您没有在问题的初始版本中显示)。它应该只包含position-independent code(PIC)所以不能产生object filerelocationR_X86_64_16(在你编辑的问题中,mov sp, main显然不是PIC,你应该使用指令指针相对数据访问x86-64 , 并且不能在 nasm 文件和 C 文件中同时定义 main,并且在链接时不能混合使用 16 位模式和 64 位模式。

研究ELF,然后研究x86-64 ABI,以了解 PIC 文件中允许哪些类型的重定位(以及汇编程序文件应遵循哪些约束来生成 PIC 目标文件)。

使用objdump(1)readelf(1) 来检查对象文件(以及共享对象和可执行文件)。

一旦您的 nasm 代码生成 PIC 目标文件,请与 gccuse gcc -v 链接以了解幕后发生的事情(您会看到额外的库和目标文件,包括 crt0使用-lgcc-lc)。

也许您需要了解更好的编译和链接。阅读 Levine 的书Linkers and Loaders、Drepper 的论文How To Write Shared Libraries,以及-关于编译-Dragon book

您可能想与gcc 链接,但使用您自己的linker script。另请参阅this 对一个非常相关的问题的回答(可能与您的动机相似);那里的参考资料与您高度相关。

PS。您的问题缺乏动机和背景(它没有MCVE,但需要一个)并且可能是一些XY problem。我猜你在Linux上。我强烈建议将您的实际完整代码 - 甚至是错误的 - (可能在 githubgitlab 或其他地方)发布为 free software 以获得潜在的帮助。 强烈建议使用现有的引导加载程序(可能是GRUB),并将您的精力集中在您的操作系统代码上(应该作为免费软件发布,以获得一些反馈)。

【讨论】:

  • 您在其他地方的 cmets 表明您甚至不了解引导加载程序有多么复杂和神秘(由于历史原因:BIOS 需要能够引导 30 年历史的系统)。真的,放弃你的引导加载程序(几个月的工作,即使对于专家来说也是如此)并专注于你的操作系统(你会学到更多,并且这样做可能会更有趣)
  • 我真的不明白引导加载程序有多么复杂和神秘,这就是为什么我试图编写一个,即使这需要一些时间。
  • 那你应该做好失败的准备。我们有好几个人警告过你(老实说,我理解你的操作系统编码是多么令人兴奋,但我不明白你为什么要在引导加载程序上花费大量精力。你甚至可能需要对事情进行逆向工程。
  • 我做好了失败的准备,但最终我希望我能有所收获。
  • 我认为我现在不具备编写引导加载程序的知识,但我认为我可以学习这些知识。
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-26
  • 2012-01-02
相关资源
最近更新 更多