Writing a Simple Operating System — from Scratch

(Jeff_L) #1

CHAPTER 5. WRITING, BUILDING, AND LOADING YOUR


KERNEL 54


call main ; invoke main() in our C kernel
jmp $ ; Hang forever when we return from the kernel

You can see from the linecall mainthat the code simply calls a function that goes
by the name ofmain. Butmaindoes not exist as a label within this code, since it is
expected to exist within one of the other object files, such that it will be resolved to
the correct address at link time; this expectance is expressed by the directive[extern
main], at the top of the file, and the linker will fail if it doesn’t find such a label.
Previously we have compiled assembly into a raw binary format, because we wanted
to run it as boot sector code on the CPU, but for this piece of code cannot stand alone,
without having that label resolved, so we must compile it as follows as an object file,
therefore preserving meta information about the labels it must resolve:


$nasm kernelentry.asm -f elf -o kernelentry.o
The option-f elftells the assembler to output an object file of the particular
format Executable and Linking Format (ELF), which is the default format output by
out C compiler.
Now, rather that simple linking thekernel.ofile with itself to createkernel.bin,
we can link it withkernelentry.o, as follows:


$ld -o kernel.bin -Ttext 0x1000 kernelentry.o kernel.o --oformat binary
The linker respects the order of the files we gave to it on the command line, such
that the previous command will ensure ourkernelentry.owill precede the code in
kernel.o.
As before, we can reconstruct our kernel image file with the following command:
cat bootsect.bin kernel.bin > os-image
Now we can test this in Bochs, but with more reassurance that our boot-block will
find its way into the correct entry point of our kernel.


5.3 Automating Builds with Make


By now you should be fed up of having to re-type lots of commands, every time you
change a piece of code, to get some feedback on a correction or a new idea you tried.
Again, programmers have been here before, and have developed a multitude of tools
for automating the build process of software. Here we will considermake, which is the
predecessor of many of these other build tools, and which is used for building, amongst
other operating systems and applications, Linux and Minix. The basic principle ofmake
is that we specify in a configuration file (usually calledMakefile) how to convert one
file into another, such that the generation of one file may be describe to depend on the
existence of one or more other file. For example, we could write the following rule in a
Makefile, that would tellmakeexactly how to compile a C file into an object file:


kernel.o : kernel.c
gcc -ffreestanding -c kernel.c -o kernel.o
The beauty of this is that, in the same directory as the Makefile, we can now type:
Free download pdf