Compiling ARM assembler for Raspberry Pi

When compiling assembly source code on the raspberry pi we need to do the following: take your source file e.g. source.s and run the as (assembler) command to create an object file:

as -o source.o source.s

This will create an object file named source.o
We now need to link the object files together into one executable file (it’s possible that you will have multiple object files, see below for how to link multiple source files) to do this we run the ld (linker) command:

ld -o source source.o

This will have created an executable file called source. The previous steps will work fine for assembly source files assuming that you have a function called _start within your source.s file which is the entry point for our code.

Another method is to use the gcc compiler which has a built in linker. In this case we generate the object files as above. Once we have the object files we run GCC with the following command.

gcc -o source source.o

This will have the same effect as running the linker. However as we are using the C compiler our source code file needs to acknowlege this by using the entry point named main rather than _start.

If we have functions in seperate source files then we need to create multiple object files. Before we link them. This is acheived by first creating all of our object files. e.g.

as -o source.o source.s
as -o source1.o source1.s
as -o source2.o source2.s
as -o source3.o source3.s

When we have all our object files created we link them all together like:

ld -o source source.o source1.o source2.o source3.o

or using GCC:

gcc -o source source.o source1.o source2.o source3.o

Creating .img files for Bare Metal

If you are coding for bare metal then you will need to convert your file to an image file do be dropped into the OS. I usually call these files kernel.img.

The first thing that we need to do is create a .ELF file. this is done using GCC with a command similar to the following:

gcc -o kernel.elf mykernel.c

We then need to convert the .ELF file to our .IMG file. (a .ELF file is essentially already a binary file it just contains some extra pieces of information.) To convert to a .IMG we use the following or similar:

objcopy kernel.elf -O binary kernel.img

This should provide a kernel.img file that can replace a kernel file on raspbian for example and is essentially a new operating system.

A Note on file formats

.s is our source code in assembly language.
.c is our source code file written in C which is a higher level language than assembly.
.o is an object file, which is a conversion of our source files into machine code, they are a little like libraries in a way as they contain non directly executable code, and need to be compiled into an executable before they can run.
.elf is an executable and linkable format file, and is similar to an object file, but they contain the full program. Whereas a .o file could contain references to external symbols from libraries or other object files.
.img is a binary file of our executable stored as a disc image.

A Note on compiler commands

as starts our assembly compiler. Feed it with .s files.
gcc start our c compiler. Feed it with .c files.
ld starts our linker. This links our object files together that we created with as or gcc into a single binary file. Feed it with .o files.
objcopy converts between binary file formats.