In applications programming, the main() function is usually
described as the first function to receive control. However,
the real entry is a function called _start(), and is typically
defined by crt1.o. This _start() sets up the environment, opens
the default descriptors, and then calls the application's
main() function. But for an operating system, there isn't any
crt1.o (at least, not yet), and so you will need to supply your
own _start function as the entry point, instead of main().
In the the first loaded file (which should be a statically
linked executable), our boot loader expects a declaration of
_start as follows:
void _start(int memSize, /* total amount of memory
installed in bytes */
char *parms, /* ASCII string typed
at the boot prompt */
struct boot_dir *loadedfiles);
The last parameter, loadedfiles
, is struct of type
boot_dir
which is a structure that contains an
array of "file" objects that contain pointers to the individual
files. A description of the bootloader system is a must look at to
get the os properly booted.
You need to compile your kernel into an ELF executable
format. The raw kernel file will always be loaded at 0x100000
(1MB), so the text and data segment locations in the file need
to coincide with their locations in memory. For ELF, specifying
the options '-dN -Ttext 0x100080' to ld will assign space to
common symbols in the file, merge the text and data segments,
and start the text segment immediately after the header (which
is where it is in the file anyway). For the new uBoot system,
the entry point needs to be at 0x101080 because the first 4K is
taken by the boot directory entry Note that the linker does not
have to create the output binary in this way; however, for
reasons of simplicity, the boot loader does not actually
interpret the kernel binary.