gcc - 将 NASM 和 64 位 C 代码编译并链接到引导加载程序中

标签 gcc x86 nasm ld bootloader

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

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

  1. 如何编译并链接 nasm 文件和 C 文件?
  2. 编译文件时,应该编译为16位还是64位?因为我要从 16 位切换到 64 位。
  3. 如何将更多文件从 C 语言或汇编语言添加到项目中?

我重写了问题以使我的目标更清晰,因此如果需要源代码请告诉我添加它。

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

最佳答案

since I am also linking a nasm file with the C file, it spits an error from the nasm object file, which is relocation R_X86_64_16 against .text' can not be used when making a shared object; recompile with -fPIC

您的问题之一可能是在 nasm 汇编程序文件中(您在问题的初始版本中没有显示该文件)。它应该只包含 position-independent code (PIC)因此无法生成 object filerelocation R_X86_64_16 (在您编辑的问题中, mov sp, main 显然不是 PIC,您应该使用 x86-64 的指令指针相对数据访问,并且您不能定义 main 都在 nasm 文件和 C 文件中,并且链接时不能混合 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 )并将精力集中在操作系统代码上(应该作为免费软件发布,以获得一些反馈)。

关于gcc - 将 NASM 和 64 位 C 代码编译并链接到引导加载程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51939790/

相关文章:

gcc - 编译器如何跨平台(硬件)?

x86 - 为什么主 PIC 的中断结束会导致三重故障(重启)?

include - NASM - 相关包含文件

assembly - 有没有办法用 int 13h 读取放在 head = 1 上的内核?

gcc - 如何在gcc中静态初始化__m128i数组?

c++ - Boost tread 代码在 VC++ 下编译但在 GCC 下不编译 : how to get better debug info

c++ - 当函数采用有符号 int 时,将 float 参数转换为无符号

c - 从 C 程序读取标志寄存器

c# - 是否有任何好的 VB/C# x86 反汇编程序库?

assembly - 实模式下的自定义 IRQ 处理程序