OSDev.org
https://forum.osdev.org/

Problem printing string?
https://forum.osdev.org/viewtopic.php?f=1&t=33743
Page 1 of 1

Author:  thumble [ Wed Jun 26, 2019 6:17 pm ]
Post subject:  Problem printing string?

I finally got into protected mode but there are still plenty of weird problems.

I wrote some small functions to print strings:

Code:
unsigned int strlen(const char *string) {
   
   for(unsigned int length = 0; string[length] != 0; length++);
   
   return length;
}

void printString(const char *string) {
   
   for(unsigned int index = 0; index < strlen(string); index++) {
      putChar(string[index]);   
   }
   
}


The weird thing is, this works:

Code:
const char text[] = "Hello.\n";
printString(text);


However, this does *not* work:

Code:
const char *text = "Hello.\n";
printString(text);


I thought that maybe the string wasn't being loaded but QEMU confirms that the string is being loaded into memory. My putchar() works without any surprises (that I know of).

I'm kind of stumped. What could cause this?

Author:  MichaelPetch [ Wed Jun 26, 2019 7:59 pm ]
Post subject:  Re: Problem printing string?

Doesn't work is a bit vague. In what way doesn't it work? Strange colors and symbols are printed? Nothing prints at all?

I know you say that QEMU says the string is in memory. I question whether that is true or not. What you are describing is what I'd normally see if someone wrote a custom bootloader but they didn't read enough sectors into memory to load the entire kernel. In the case of `const char text[] = "Hello.\n";` the string will be placed in the data section (or an rodata*/rdata*) separate from the code. Often the data/rdata*/rodata* resides further into a kernel's binary image. `const char *text = "Hello.\n";` has the string placed on the stack and *usually* is part of the code.

Without seeing your code it is hard to say. Do you have it on github or some other service?

Are you building this on Windows? Linux? MacOS? other?

Author:  songziming [ Wed Jun 26, 2019 8:46 pm ]
Post subject:  Re: Problem printing string?

I think your strlen function should not compile at all, you are returning a variable out of its scope.

Your function:

Code:
unsigned int strlen(const char *string) {
   for(unsigned int length = 0; string[length] != 0; length++);
   return length;
}


Should be:

Code:
unsigned int strlen(const char *string) {
   unsigned int length;
   for (length = 0; string[length] != 0; length++) ;
   return length;
}

Author:  thumble [ Wed Jun 26, 2019 10:07 pm ]
Post subject:  Re: Problem printing string?

Sorry for the lack of clarification. Nothing prints right now.

I'm building on WSL on Windows 10 with a cross compiler targeted at i386.

I'm pretty sure that the string is in memory. Currently I compile my kernel to a raw binary and load it into memory, so I can see where everything should end up in memory. From the QEMU monitor, I the bytes of the string show up as expected.

My code is on github, but it's a little messy. https://github.com/adrian154/testOS

As for the strlen error, that one really slipped by me. However, I changed it and it still doesn't work, which convinces me that the crux of the issue is elsewhere.

Author:  thumble [ Wed Jun 26, 2019 11:38 pm ]
Post subject:  Re: Problem printing string?

Well, I figured out a fix (?)

The kernel is loaded at 0x8400 right now (though I plan on changing that) but this gets the message on screen:

Code:
printString((const char *)text + 0x8400);


I probably screwed up my linker script so I'll work on fixing that.

edit: I guess my problem has shifted to why constant offsets are wrong but everything else works (calling works as expected and all those offsets aren't screwed up)

Author:  MichaelPetch [ Wed Jun 26, 2019 11:50 pm ]
Post subject:  Re: Problem printing string?

My best guess is that your linker script doesn't have:
Code:
. = 0x8400
or it isn't defined properly. If you gave to add 0x8400 to memory addresses then it sounds like the origin point (VMA) was set to 0x0000 rather than 0x8400. If you show your linker script we might be able to help.

Author:  MichaelPetch [ Wed Jun 26, 2019 11:54 pm ]
Post subject:  Re: Problem printing string?

I realized after my last post you put a github link. Your linker script has:
Code:
OUTPUT_FORMAT("binary")
ENTRY(start)

phys = 0x00008400;

SECTIONS
{
   .text BLOCK(4K) : ALIGN(4K) {
      *(.text)
   }
   
   .rodata BLOCK(4K) : ALIGN(4K) {
      *(.rodata)
   }
   
   .data BLOCK(4K) : ALIGN(4K) {
      *(.data)
   }
   
   .bss BLOCK(4K) : ALIGN(4K) {
      *(.bss)
   }
   
   end = .;
}
The problem is you define `phys` to be 0x8400 but you never set the VMA (origin point) to that value. `phys` is like a constant. Nothing happens if you don't use it. Maybe try:
Code:
OUTPUT_FORMAT("binary")
ENTRY(start)

phys = 0x00008400;

SECTIONS
{
   . = phys;

   .text BLOCK(4K) : ALIGN(4K) {
      *(.text)
   }
   
   .rodata BLOCK(4K) : ALIGN(4K) {
      *(.rodata)
   }
   
   .data BLOCK(4K) : ALIGN(4K) {
      *(.data)
   }
   
   .bss BLOCK(4K) : ALIGN(4K) {
      *(.bss)
   }
   
   end = .;
}

Author:  thumble [ Thu Jun 27, 2019 12:33 am ]
Post subject:  Re: Problem printing string?

I'm still a bit fuzzy about why this worked but setting the origin point and getting rid of 4K boundary alignment fixed the problem. Thanks for the help Michael!

Author:  MichaelPetch [ Thu Jun 27, 2019 6:01 am ]
Post subject:  Re: Problem printing string?

I answered late last night and wasn't paying much attention. 0x8400 is not aligned on a 4KiB boundary. So your linker script will start the code at 0x9000 (which is on a 4KiB boundary). You then load the code generated to start at 0x9000 to 0x8400 and that causes problems. By removing the 4KiB alignment it worked because then the kernel was generated starting at 0x8400 which is the location you loaded it in memory.

Author:  saltlamp [ Mon Jul 01, 2019 3:20 pm ]
Post subject:  Re: Problem printing string?

The problem is because in the second example, you are not initializating the string. You are simply pointing some list of values in memory, which may or may not exist. In the first example, you are setting each value, one after another, to be "hello world\n"

If you go with the second option, you need something like 'malloc' to allocate memory for the string, other wise the print function has nothing to print.

Hopefully this helps!

Author:  MichaelPetch [ Mon Jul 01, 2019 3:25 pm ]
Post subject:  Re: Problem printing string?

saltlamp wrote:
If you go with the second option, you need something like 'malloc' to allocate memory for the string, other wise the print function has nothing to print.

You don't need mallo for doing something like:
Code:
const char *text = "Hello.\n";
That string will be placed in a data section (.rodata/.data etc) inside the kernel. As long as the entire kernel is read into memory the string will be in memory.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/