Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
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).
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?
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.
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.
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)
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.
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:
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!
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.
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.
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.
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.