Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I produce plain binary from object files?

How should I produce raw binary file from two object (.o) files?

I want the plain binary format produced by nasm -f bin when compiling a .asm file, but for .o files.

By a plain binary, I mean a file which contains only the instructions, not some extra information, as many executable files contain a lot of extra helpful information.

See http://www.nasm.us/doc/nasmdoc7.html for information on that.

PS: I want to make a "plain binary" to start in QEMU.

like image 392
Pratik Singhal Avatar asked Aug 22 '14 08:08

Pratik Singhal


People also ask

Is object file same as binary file?

An object file contains the same instructions in machine-readable, binary form. Assembly files can be translated to object files by the assembler (as). An LLVM bitcode file (. bc) contains LLVM instructions in binary form.

How are binary files made?

If the compiler generates bytecode, the bytecode will eventually be converted to machine code. Machine code is submitted to a computer's processor in the form of binary files. The machine code files must target a specific computer platform, which refers to the combination of operating system and hardware architecture.

Is object code a binary file?

In computing, object code or object module is the product of a compiler. In a general sense object code is a sequence of statements or instructions in a computer language, usually a machine code language (i.e., binary) or an intermediate language such as register transfer language (RTL).

Which method is used to write the objects in a binary file?

dump(object , file_handler) - used to write any object to the binary file. Object=load(file_handler) - used to read object from the binary file.


2 Answers

This brings back memories. I'm sure there is a better way to do this with linker scripts, but this is how I did it when I was young and stupid:

# compile some files
gcc -c -nostdlib -nostartfiles -nodefaultlibs -fno-builtin kernel.c -o kernel.o
gcc -c -nostdlib -nostartfiles -nodefaultlibs -fno-builtin io.c -o io.o

# link files and place code at known address so we can jump there from asm
ld -Ttext 0x100000 kernel.o io.o -o kernel.out

# get a flat binary
objcopy -S -O binary kernel.out kernel.bin

The file kernel.c started with

__asm__("call _kmain");
__asm__("ret");

void kmain(void) { ... }

The fun part is writing the loader in assembler.

like image 98
Christoph Avatar answered Oct 13 '22 23:10

Christoph


ld --oformat binary is a more direct option:

ld --oformat binary -o main.img -Ttext 0x7C00 main.o

The downside of this method is that I don't think it is possible to reuse the symbols to debug, as we'd want something like:

qemu-system-i386 -hda main.img -S -s &
gdb main.elf -ex 'target remote localhost:1234'

So in that case you should stick to objcopy. See also: https://stackoverflow.com/a/32960272/895245

Also make sure that you use your own clean linker script: https://stackoverflow.com/a/32594933/895245

Repository with working examples for some common cases:

  • boot sectors
  • multiboot interfacing with C

Similar question: How to generate plain binaries like nasm -f bin with the GNU GAS assembler?