8
votes

I am in the process of writing a small operating system in C. I have written a bootloader and I'm now trying to get a simple C file (the "kernel") to compile with gcc:

int main(void) { return 0; }

I compile the file with the following command:

gcc kernel.c -o kernel.o -nostdlib -nostartfiles

I use the linker to create the final image using this command:

ld kernel.o -o kernel.bin -T linker.ld --oformat=binary

The contents of the linker.ld file are as follows:

SECTIONS
{
    . = 0x7e00;

    .text ALIGN (0x00) :
    {
        *(.text)
    }
}

(The bootloader loads the image at address 0x7e00.)

This seems to work quite well - ld produces a 128-byte file containing the following instructions in the first 11 bytes:

00000000 55                             push    ebp
00000001 48                             dec eax
00000002 89 E5                          mov ebp, esp
00000004 B8 00 00 00 00                 mov eax, 0x00000000
00000009 5D                             pop ebp
0000000A C3                             ret

However, I can't figure out what the other 117 bytes are for. Disassembling them seems to produce a bunch of garbage that doesn't make any sense. The existence of the additional bytes has me wondering if I'm doing something wrong.

Should I be concerned?

hexdump of the file

2
Oh, and yes, I do realize the code generated needs to run in protected mode. The bootloader will take care of switching the CPU to protected mode. - Nathan Osman
@Aftnix: I'm generating a flat binary file. There should be no ELF header. - Nathan Osman
How about after: strip --strip-all -R .note -R .comment kernel.bin - technosaurus
Perhaps that's debugging information? Try something like: ld kernel.o -o --strip-all kernel.bin -T linker.ld --oformat=binary - Dougvj

2 Answers

12
votes

These are additional sections, which were not stripped and not discarded. You want your linker.ld file to look like this:

SECTIONS
{
    . = 0x7e00;

    .text ALIGN (0x00) :
    {
        *(.text)
    }

    /DISCARD/ :
    {
        *(.comment)
        *(.eh_frame_hdr)
        *(.eh_frame)
    }
}

I know what sections to discard from the output of objdump -t kernel.o.

-1
votes

Simple, you're using gcc, and it always put its initialization code before passing control to your main. What's on that start up code I don't know, but they are there. As you may see there's also an comment 'GNU' on your binary, you can't print specific sectors by using objdump -s -j 'section name'.