Page 1 of 1

Printing to screen.

Posted: Wed Aug 02, 2006 10:59 pm
by kenneth_phough
I am working on my video driver for my kernel, and I have been able to print characters (i.e. 'a') and clear the screen but not strings (i.e. "hello world„0").
I have noticed that if I declare an array or have a pointer point to a string and I compile and link it, bochs doesn't run it.
The following code is all I added to my screen.c:

Code: Select all

char *msg="hello world„0";
And if I compile screen.c and link it with the rest and run it, it won't work.
So i decided to open my kernel.bin with kHexeditor and to my suprise the following showed up:

Code: Select all

hello.world......................................(etc.) 
Kernel.bin had the words hello world at the begining and the rest was filled up with zeros.
Would anyone know what might be the problem? Could it be the linker script?
I use the following tools and OS:
SuSE Linux 10.1
gcc
ld
nasm

Thanks,
Kenneth

Posted: Thu Aug 03, 2006 1:08 am
by bubach
I think it's the linker script, yes. I've seen this posted a couple of times on the mega-tokyo forum.

Unfortunately their search function sucks, so I can't find any post with it and the solution...

Posted: Thu Aug 03, 2006 8:42 am
by gaf
Hello
As string literals are constant, they get stored in the read-only section of your executale. You thus probably only forgot to include the rodata section in your linker script:

Code: Select all

SECTIONS
{
  .text :
  {
    *(.text)
    *(.rodata*)
  }
  ...
}
regards,
gaf

Posted: Fri Aug 04, 2006 5:56 am
by kenneth_phough
Thank you very much! It worked! Would it make a difference if I do the following?

Code: Select all

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    *(.rodata*)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}
or does it have to be under *(.text).
Forgive me if I asked a stupid question, I'm new to LD scripting. :oops:

Yours,
Kenneth

Posted: Fri Aug 04, 2006 9:05 am
by gaf
It's basically a matter of personal preference: Merging text and rodata makes does some sense as both sections are read-only, but I can also why you'd want to combine rodata with the regular data.

As we're talking about a operating system executable, it really doesn't make any difference. Evenually all of the code is put into the same binary image, which then gets loaded to some regular read/write memory by the boot-loader. For a user-level application, there might however be some advantage in putting rodata into the text section (or using a special rodata section, if the executable-format permits that). When starting the executable, the operating system then knows, that rodata is meant to be read-only. It might thus enforce this policy by putting the section into a read-only area of memory, that is protected agains writes by segmentation or paging. Some computer architectures may even have a special read-only memory that can be used for such purposes.

By the way: The AT() and ALIGN() directives in your linker-script are in my opinion not really needed. You might remove them to make the script easier to read..

regards,
gaf

Posted: Sat Aug 05, 2006 6:23 am
by kenneth_phough
The only reason I thought I might put *(.rodata*) under data was because they are both data, just that one is hardcoded.
Thanks for the advice :wink:
Yours,
Kenneth