Page 1 of 1

Printing to screen...

Posted: Thu Jan 26, 2006 12:59 pm
by Abolo
I am having a slight problem getting a kernel to boot which I wrote (copied and pasted:)) from http://www.osdever.net/bkerndev/index.php?the_id=90

I have basically reached the page about printing onscreen (e.g. a simple hello world message). The problem is that it is not printing this "hello world" message.

I am using Debian 3.1 and bochs. I found a 1.44 grub image file for use with bochs. Using the kernel supplied on that webpage I can get it to boot her/his one without any problems. Compiling and using my own it will not work.

Now, in my start.asm file where it should call the main method in my main.c I had to remove the underscore from both
extern _main
call _main
to get it to link successfully.
Otherwise it generated an error saying "undefined reference to _main"... when I remove the underscore it gives no error.

Now to be totally honest I am very new to all this, and I would appreciate any information or even a general direction to look in.

I am assuming the underscore may somehow be causing the problem because all my code seems to be the same as his except that part....

One other thing, is there any way for me to check to see whether my main function is actually being called from start.asm ?

Re:Printing to screen...

Posted: Thu Jan 26, 2006 2:13 pm
by OZ
hi there,
that tutorial is a really nice point to start from - even better if you know where to search for further straight information.
Take a look at the forums FAQ and specific to your problem Compilers >> gcc >> calling conventions . (for the underscore problem)

Can't tell you why it doesn't print if you don't at least paste the kernels main function, as that is what you edited yourself.
Apart from that you should test if the main function is reached or if bochs tells you about any errors before.
You could do that by inserting an

Code: Select all

__asm__("hlt");
just after entering the main function, if that gets executed bochs will tell you that it halted with a hlt and if=0
If thats not the case you never reach the C part and therefore no printing takes place.

hope it helps

Re:Printing to screen...

Posted: Thu Jan 26, 2006 2:56 pm
by Abolo
Thank you for the reply. The "__asm__("hlt");" worked, at least know I know it's entering my main... which will allow me to sleep peacefully for one night:)

Re:Printing to screen...

Posted: Fri Feb 03, 2006 10:49 am
by Antwarrior
it's just the calling convention inside your object file.
When you write a function , say setup_gdt

it appears in your object file as _setup_gdt.
That's how you would hav to call it. I " think " with newer versions of ld ( linker ) accept references to functions without the under score.

I had the same problem too.... that's the only explanation I can come up with. ...

Re:Printing to screen...

Posted: Fri Feb 03, 2006 12:39 pm
by beyondsociety
I am using Debian 3.1 and bochs. Now, in my start.asm file where it should call the main method in my main.c ,I had to remove the underscore from both

extern _main
call _main

to get it to link successfully.Otherwise it generated an error saying "undefined reference to _main"... when I remove the underscore it gives no error.
Since you are using debian which is a linux based os, the main output for the linker is elf or aout which requires no underscore for the object files. If you were using some other format like Coff, PE, etc. you would need to add the underscore.

In that tutorial he is using djgpp which is a port of the linux gnu tools to windows. So in order for the asm code to link, you have to supply the underscore.

Edit: Took a look at the tutorial and he is compiling the start.asm file to an aout format which requires no underscore on your os, but does require one on windows which is what he's using.

Re:Printing to screen...

Posted: Sat Feb 04, 2006 10:34 am
by Abolo
Thank you for the replies, very much appreciated.
I had little time lately to play around with this but I am back at it.

My main() does seem to be executing, the reason it was not printing my string "Hello World" was due to the strlen function always returning 0.

The puts(char *str) displays my string. It relies upon strlen(char *str) to get the length of the string and then uses a putch(char c) function to actually print each character of it.
The putch(char c) function works grand and prints to the screen(thus nothing wrong with the screen driver and so on).

The problem is with my strlen: (See below)

-------------------------------
size_t strlen(const char *str)
{
size_t retval;
for(retval = 0; *str != '\0'; str++) retval++;
return retval;
}
------------------------------

For whatever reason this always return a 0. Now, having added a putch(*str + 48) at the begenning of this method it displays a 0 to my screen. Indicating that whatever value *str points to is a 0.

Now, after this I am confused and don't know what it is.
Do I have to set up data segments or alike (or do I even have a clue what I am talking about. <- Rhetorical question)?

Any help would be greatly appreciated and thank you in advance.

Re:Printing to screen...

Posted: Sat Feb 04, 2006 12:47 pm
by OZ
perhaps your linker file - is there a .rodata entry?

Re:Printing to screen...

Posted: Sat Feb 04, 2006 1:01 pm
by Abolo
there is a
-----------------------------
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
-----------------------------

Ok, if at the top of my main() do a
char hello[] = {'h','e','l','l','o','\0'};

putch(strlen(hello) + 48);

i get the proper sting length of 5

However I do a strlen("hello") i get a 0

This is something I am very confused about.

Re:Printing to screen...

Posted: Sat Feb 04, 2006 5:22 pm
by JoeKayzA
ok, you need to add an entry for the .rodata section (the same way you it with the .data section).

This is where the compiler will put the string "hello" when you use it as a literal. In your case this section is missing, thus the pointers to "hello" go to some bogus location, which is probably initialized to zero by the emulator (this is one of the rather 'bad' attitudes under bochs).

When you define the string as

Code: Select all

char hello[] = {'h','e','l','l','o','\0'};
the compiler will put it directly on the stack, therefore it works.

cheers Joe

Re:Printing to screen...

Posted: Sun Feb 05, 2006 11:19 am
by Abolo
Splendid, thank you, it works:)

And for future reference in case an idiot like myself gets stuck on this the linker file I used was
http://abolo.org/~abolo/osdev/brans/link.ld


Cheers for the help everybody, and I am sure there will be many more questions like this one. :)