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 :
(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:
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:
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
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:
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
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