Page 1 of 1

[Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 12:31 pm
by gerenjo
Hi everyone,

I began my own OS a couple of weeks ago. I spent 1 full week learning assembly language and writing my bootloader.
That wasn't that hard for me though, since I know C quite well.
However, i encounter difficulties when I try to use C code. How exactly can I jump from an assembly routine (my stage2) to a C function, which would be my kmain() ?
I've been following plenty of tutorials lately, but I am stuck at the same step each time.

For instance, I followed the "barebones tutorial" that everyone here knows, on the wiki. I easily can print a character at the top of screen, which is great.
However, as soon as i try to do something like that :

Code: Select all

char *str = "Hello world!";
videomem[0] = str[0];
It does not work anymore. Nothing outputs, but the kernel does not crash, since I still can print characters llike that after :

Code: Select all

videomem[0] = 'H';
(I fill the videoram with 0x07 before, I dont )

I noticed the same thing with the tutorial available here : http://www.osdever.net/bkerndev/Docs/basickernel.htm
I imagine that some of you know this one too. The result was exactly the same : everything works fine until I try to use strings :(

Can anyone tell me what I should fix to have real strings to work in my C kernel ?
Then how can I jump from an assembly routine to an actual C function ? I guess the output format of my compiled kernel will be ELF.

Thanks,

A random noob :)

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 12:48 pm
by Solar
Make sure your linker script actually includes .rodata* in your kernel binary - that's the section strings end up in. Individual characters don't - it's a very common beginner mistake.

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 1:01 pm
by CodeCat
Don't forget that video memory consists of 16-bit words, not bytes. The first byte of each word is the character, the second is the colour attributes. If the attribute bit is 0 you'll get black on black, so you won't see anything.

EDIT: Calling a C function is done by following the cdecl calling convention. The basic rules for a function call are:

- push the parameters on the stack in reverse order, starting from the rightmost one (the leftmost parameter is pushed last)
- call the function (using the CALL instruction)
- remove the parameters from the stack

For your kmain function this would be nothing more than:

Code: Select all

call kmain
Note that there is nothing mandating that kmain actually has to return, but to make sure things don't get messed up if it does return, you should add a HLT instruction and an infinite loop at the end after the call to kmain:

Code: Select all

cli
loop:
hlt
jmp loop

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 1:46 pm
by gerenjo
Yeah I know all this.
I just copy/pasted the linker scripts given in those two tutorials, and it does not work with strings.
As I said, i fill the video ram bytes with 0x7, so I get white text on black background.

The linker script copy/pasted from the bare bones tutorial includes the .rodata AFTER .text, so it doesn't mess the code up.
see: http://wiki.osdev.org/Bare_bones
Again, I don't see any reasons for this not to work:

Code: Select all

char *str = "toto";
videoram[0] = str[0];
whereas THAT works

Code: Select all

videoram[0] = 't';
Is there anything I don't understand or forget to do ? :/
(Assume my code is exactly the same as in the bare bones tutorial)

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 1:50 pm
by Combuster
Are you using the GCC Cross-Compiler? If not the section may have a different name (try .rdata, or better, use objdump)

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 1:51 pm
by neonek
Hello gerenjo

Maybe JamesM tutorial will help you. For printing functions read The Screen section and read this.

Regards,
Mark

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 2:13 pm
by gerenjo
Thank you, I will study this a bit. (more read!)

Re: [Newbie] Switching from assembly to C after boot

Posted: Tue Feb 03, 2009 7:59 pm
by Troy Martin
Am I the only one that found a painfully obvious one? Instead of this:

Code: Select all

videoram[0] = str[0];
Use this:

Code: Select all

videoram[0] = *str++; /* put the byte pointed to by str and increase the pointer! */

Re: [Newbie] Switching from assembly to C after boot

Posted: Wed Feb 04, 2009 3:18 am
by AJ
Hi,

I think the OP was only trying to put the first character on the screen to prove it works. What's the point of incrementing the pointer if you only want to display the first character?

Cheers,
Adam

Re: [Newbie] Switching from assembly to C after boot

Posted: Wed Feb 04, 2009 4:28 am
by Solar
Compile your C file to object code (-c).

Use objdump to make sure the string is in the object code, and note the name of the section it is stored in.

Double-check your linker script does include that section.

Compile your kernel binary.

Use objdump to make sure the string is in the binary.

Find out which step fails by logic deduction.

Return here with the additional info.

Re: [Newbie] Switching from assembly to C after boot

Posted: Wed Feb 04, 2009 12:38 pm
by abachler

Code: Select all

char str[] = "Hello World!";
has to be declared as a global variable, so that it is allocated at compile time, not at run-time (the pointer , not the string).

In general you should avoid the use of local variables when writing kernel code, at least until you get more experience with what you can and cannot do with them.

Re: [Newbie] Switching from assembly to C after boot

Posted: Wed Feb 04, 2009 1:00 pm
by Combuster
In general you should avoid the use of local variables when writing kernel code, at least until you get more experience with what you can and cannot do with them.
What a horrible piece of advice. If you're in such a state local variables can not be used then you have some serious problems yourself (including your knowledge of the language).

Re: [Newbie] Switching from assembly to C after boot

Posted: Wed Feb 04, 2009 1:54 pm
by jal
As someone already mentioned, try using str[] instead of *str. See if that works. If so, I'm a bit lost why, but then again I don't know the deep dark secrets of C variable initialization.


JAL