Compiling and linking NASM and 64-bit C code toget

2019-06-06 02:25发布

问题:

This question already has an answer here:

  • Relocation error when compiling NASM code in 64-bit mode 1 answer

I made a very simple 1 stage bootloader that does two main things: it switches from 16 bit real mode to 64 bit long mode, and it read the next few sectors from the hard disk that are for initiating the basic kernel.

For the basic kernel, I am trying to write code in C instead of assembly, and I have some questions regarding that:

  1. How should I compile and link the nasm file and the C file?
  2. When compiling the files, should I compile to 16 bit or 64 bit? since I am switching from 16 to 64 bits.
  3. How would I add more files from either C or assembly to the project?

I rewrote the question to make my goal more clear, so if source code is needed tell me to add it.

Code: https://github.com/LatKid/BasicBootloaderNASMC

回答1:

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

One of your issues is probably inside that nasm assembler file (which you don't show in the initial version of your question). It should contain only position-independent code (PIC) so cannot produce an object file with relocation R_X86_64_16 (In your edited question, mov sp, main is obviously not PIC, you should use instruction pointer relative data access of x86-64, and you cannot define main both in your nasm file and in a C file, and you cannot mix 16 bits mode with 64 bits mode when linking).

Study ELF, then the x86-64 ABI to understand what kind of relocations are permitted in a PIC file (and what constraints an assembler file should follow to produce a PIC object file).

Use objdump(1) & readelf(1) to inspect object files (and shared objects and executables).

Once your nasm code produces a PIC object file, link with gcc and use gcc -v to understand what happens under the hoods (you'll see that extra libraries and object files, including crt0 ones, -lgcc and -lc, are used).

Perhaps you need to understand better compilation and linking. Read Levine's book Linkers and Loaders, Drepper's paper How To Write Shared Libraries, and -about compilation- the Dragon book.

You might want to link with gcc but use your own linker script. See also this answer to a very related question (probably with motivations similar to yours); the references there are highly relevant for you.

PS. Your question lacks motivation and context (it has no MCVE but needs one) and might be some XY problem. I guess you are on Linux. I strongly recommend publishing your actual full code -even buggy- (perhaps on github or gitlab or elsewhere) as free software to get potential help. I strongly recommend using an existing bootloader (probably GRUB) and focus your efforts on your OS code (which should be published as free software, to get some feedback).