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

时间:2018-08-20 23:40:25

标签: gcc x86 nasm ld bootloader

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

  

因为我还将nasm文件也链接到C文件,所以它从nasm目标文件中吐出了一个错误,即在创建共享库时不能使用R.X86_64_16对.text的重定位;用-fPIC重新编译

您的问题之一可能在该nasm汇编文件中(在问题的初始版本中未显示)。它应该只包含position-independent code(PIC),因此不能产生带有object file R_X86_64_16的{​​{3}}(在您编辑的问题中,mov sp, main显然不是PIC,您应该使用relocation的指令指针相对数据访问,并且不能同时在main文件和C文件中定义nasm,并且在链接时不能将16位模式与64位模式混合使用)。

研究x86-64,然后研究ELF,以了解PIC文件中允许哪种重定位(以及汇编程序文件应遵循哪些约束条件以生成PIC对象文件)。

使用x86-64 ABIobjdump(1)检查对象文件(以及共享对象和可执行文件)。

一旦您的nasm代码生成了PIC目标文件,请与gccreadelf(1) gcc -v链接以了解幕后情况(您会看到额外的库和目标文件,包括use个文件,-lgcc-lc)。

也许您需要了解更好的编译和链接。阅读Levine的书crt0,Drepper的论文Linkers and Loaders和有关编译的How To Write Shared Libraries

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

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