How big should a compiled "Hello World" C kernel be

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
deathly809
Posts: 5
Joined: Mon Jul 25, 2011 8:22 am

How big should a compiled "Hello World" C kernel be

Post by deathly809 »

Hello,

Here is my setup:
Windows
nasm
gcc
virtual box

What I am doing:
Compile boot loader and kernel where the boot loader will load the kernel into memory and then jump to it. (Depending on kernel maybe in protected mode)
I am using nasm to compile my boot loader directly into a binary flat file and then gcc to compile my kernel from C. To compile my kernel I use these commands:

gcc -Wall -Wextra -Werror -nostdlib -nostartfiles -nodefaultlibs -o kernel.o -c kernel.c
C:\MinGW\mingw32\bin\ld.exe kernel.o -o kernel.bin
objcopy -O binary kernel.tmp kernel.bin

My code for my kernel is this:

Code: Select all

void kmain( )
{
	asm("cli");
	
	char* buffer = "Hello, world!",
            * vmem   = (char*)0xB8000;
        
        while (*buffer) {
                *vmem++ = *buffer++;
                *vmem++ = 0x07;
        }
        
        for (;;)
                asm("hlt");

}
The problem is that this code compiles and links into a 8k file. The output from the gcc is only a 486 byte file and
the linker blows it up to 3.7k and objcopy then makes it 8k.

I have a nagging feeling that this is probably not correct and my linking skills are almost non-existent. I
have seen where some people have compiled the boot loader and kernel to objects then link the too together
but I am not really comfortable with that idea.

Is anyone aware if the size is correct? As a test I read somewhere that I can compile it straight to assembly with
these commands:
gcc -c kernel.c
objcopy -O binary kernel.o kernel.bin

however if I do that then the first line in the assembly is "Hello, Word!" which is not a instruction. I could try to jump
past it but I want to be consistent because the kernel will change and I don't want to have to keep modifying my
boot loader each time.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: How big should a compiled "Hello World" C kernel be

Post by bluemoon »

Check your linker script, did you align the code and/or data to 4K?
You can use objdump or hex editor to check the actual useful bits and see how many padding are there.
deathly809
Posts: 5
Joined: Mon Jul 25, 2011 8:22 am

Re: How big should a compiled "Hello World" C kernel be

Post by deathly809 »

This is my linker script:
C:\MinGW\mingw32\bin\ld.exe kernel.o -o kernel.bin
objcopy -O binary kernel.tmp kernel.bin

The "Hello, World!" data is located at 0x1000 (4096) which is probably not what I wanted. Also the code ends at
0x46 (70) and then pads a bunch of zeros to 0x1000 and then after my Hello, World! it is padding all the way to
the end it seems.

I have looked at the linker script in the bare bones wiki but it is for
an assembly file. I have tried to modify it but it doesn't work. Since it seems that objcopy is doing the padding
I tried to look at the man page and see if there was a way to not have padding, seems there is only a way to
add padding. I tried to remove sections and that didn't nothing.

Does anyone have a script that they know works that I can look at to see what they did?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: How big should a compiled "Hello World" C kernel be

Post by Solar »

deathly809 wrote:This is my linker script:
C:\MinGW\mingw32\bin\ld.exe kernel.o -o kernel.bin
objcopy -O binary kernel.tmp kernel.bin
That's not a "linker script". That is "linking the kernel as if it were Windows / MinGW object code" and then turning that into a flat binary...

A linker script is something like this, i.e. a set of commands telling your linker what to do exactly (i.e., leaving out all the stuff it would normally do for Windows / MinGW object code).

Perhaps it'd be easier for you to start with the Bare Bones (and, implicitly, GCC Cross-Compiler tutorials, get those to work, and then work from there?
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: How big should a compiled "Hello World" C kernel be

Post by Combuster »

I have looked at the linker script in the bare bones wiki but it is for an assembly file.
No it's not. What do you think the C code is doing in that article?

You also seem to have missed the Getting Started and the first few lines of the barebones article. After all, you are building a windows application and then assuming it will work properly even if there's no windows around...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
deathly809
Posts: 5
Joined: Mon Jul 25, 2011 8:22 am

Re: How big should a compiled "Hello World" C kernel be

Post by deathly809 »

Solar wrote:
deathly809 wrote:This is my linker script:
C:\MinGW\mingw32\bin\ld.exe kernel.o -o kernel.bin
objcopy -O binary kernel.tmp kernel.bin
That's not a "linker script". That is "linking the kernel as if it were Windows / MinGW object code" and then turning that into a flat binary...

A linker script is something like this, i.e. a set of commands telling your linker what to do exactly (i.e., leaving out all the stuff it would normally do for Windows / MinGW object code).

Perhaps it'd be easier for you to start with the Bare Bones (and, implicitly, GCC Cross-Compiler tutorials, get those to work, and then work from there?
Yeah I know it is not a linker script in the sense you were talking about. It is just the closest thing that I have to it. I have used the linker script that was in the bare bones wiki to try and
make it work but that didn't seem to work out so well with it padding a punch of zeros between the text and data sections and after the data section.

I have looked at the bare-bones stuff and I don't really feel that is the direction I want to go. Really all I want to do is for gcc to
compile the kernel to straight assembly without any extra stuff and then just use the boot loader to load it then jump to it after
entering protected mode.
Combuster wrote:
I have looked at the linker script in the bare bones wiki but it is for an assembly file.
No it's not. What do you think the C code is doing in that article?

You also seem to have missed the Getting Started and the first few lines of the barebones article. After all, you are building a windows application and then assuming it will work properly even if there's no windows around...
I have read those articles already and they don't answer my question, why did you link to them again? What are you talking about with windows applications? That has nothing to do with what I said. Maybe you are confused, as I pointed out I am compiling it into a object file then linking it (really just setting offsets) and making it a binary. What does your comment have to do with anything?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: How big should a compiled "Hello World" C kernel be

Post by Brendan »

Hi,
deathly809 wrote:
Combuster wrote:You also seem to have missed the Getting Started and the first few lines of the barebones article. After all, you are building a windows application and then assuming it will work properly even if there's no windows around...
I have read those articles already and they don't answer my question, why did you link to them again? What are you talking about with windows applications? That has nothing to do with what I said. Maybe you are confused, as I pointed out I am compiling it into a object file then linking it (really just setting offsets) and making it a binary. What does your comment have to do with anything?
If you don't tell the linker exactly what you do want (e.g. using a linker script), then it reverts to it's default behaviour. On Windows the linker's default behaviour would be to assume you're linking a Windows application. Basically, because you don't have a linker script the linker aligns sections to 4 KiB (just like it would for a Windows application to ensure sections line up with pages so that the OS can set page attributes to reflect the section's permissions properly); and it's this 4 KiB page alignment that is causing your problem.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
deathly809
Posts: 5
Joined: Mon Jul 25, 2011 8:22 am

Re: How big should a compiled "Hello World" C kernel be

Post by deathly809 »

Brendan wrote:Hi,
deathly809 wrote:
Combuster wrote:You also seem to have missed the Getting Started and the first few lines of the barebones article. After all, you are building a windows application and then assuming it will work properly even if there's no windows around...
I have read those articles already and they don't answer my question, why did you link to them again? What are you talking about with windows applications? That has nothing to do with what I said. Maybe you are confused, as I pointed out I am compiling it into a object file then linking it (really just setting offsets) and making it a binary. What does your comment have to do with anything?
If you don't tell the linker exactly what you do want (e.g. using a linker script), then it reverts to it's default behaviour. On Windows the linker's default behaviour would be to assume you're linking a Windows application. Basically, because you don't have a linker script the linker aligns sections to 4 KiB (just like it would for a Windows application to ensure sections line up with pages so that the OS can set page attributes to reflect the section's permissions properly); and it's this 4 KiB page alignment that is causing your problem.


Cheers,

Brendan

I have tried using a linker script but it doesn't seem to change anything. In fact it outputs the same
binary object. So using a linker script seems to do nothing at all for me.
deathly809
Posts: 5
Joined: Mon Jul 25, 2011 8:22 am

Re: How big should a compiled "Hello World" C kernel be

Post by deathly809 »

Just a quick update, I have reduced the size a lot however it was because in my Makefile I was not using the right file, I think I should sleep more. However there
is still a huge amount of zeros between the end of the text and the data sections it seems. How I would reduce this I have no clue. Guess time to do some more
research into linkers and linker scripts.
Post Reply