Page 1 of 1

[Solved] Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 2:16 pm
by Lithorien
Hello everyone! :) I have an issue that I have, as yet, been unable to figure out or find an answer to. I've been searching and tweaking for the better part of a day, and have hit a brick wall, so I figured I'd ask ya'll about it.

My environment: A home rolled bootloader, MinGW's GCC and ld (compiling the C++ kernel into a PE format), and nasm (assembling my stage2 into elf format). Running inside of VirtualBox.

My problem: In my kernel, I am trying to write text to the screen by writing to video memory. I can do this in a kputch function, and my kcls function also works. But when I try to pass a C-style string into a kprintf function, my kernel won't boot - it'll load into memory (as far as I can tell), but nothing will execute.

Here's the code from the kernel, and my linker.ld file. I'll be more than happy to upload my stage2 code as well if needed. :)

kernel.cpp

Code: Select all

extern "C" {void kmain();}
void kputch(const char str);
void kprintf(const char* strptr);
void kcls();

void kmain()
{	
	kcls();
	kputch('A');
	//kprintf("Hello World."); // *****Uncomment this to break the kernel
}

void kputch(const char chr)
{
	char* vramptr = (char*)0xB8000;
	
	*vramptr = chr;
	vramptr++;
	*vramptr = 0x7;
}

void kprintf(const char* strptr)
{
	while (*strptr != 0)
	{
		kputch(*strptr);
		
		strptr++;
	}
}
linker.ld

Code: Select all

OUTPUT_FORMAT("pe-i386")
ENTRY(KSTART)
SECTIONS
{
  .text  0x100000 : {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }
  .data  : {
    data = .; _data = .; __data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss  :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .; _end = .; __end = .;
}
Notes: I have tried adding *(.rodata) below *(.text) in the linker.ld file as well, and it changes nothing. I am NOT multiboot-compatable at this point in time. My kernel is loaded at the 1MB point in memory with protected mode and the A20 gate enabled.

Thank you for any advice you can offer me! :)

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 2:42 pm
by Combuster
Are you loading a fixed size for the kernel? if so, is that still enough with the larger, kprintf-enabled kernel?

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 2:44 pm
by Lithorien
Combuster wrote:Are you loading a fixed size for the kernel? if so, is that still enough with the larger, kprintf-enabled kernel?
I'm taking the kernel off of a FAT12 formatted floppy and reading it until the EOF, then dropping that entire image into memory at the 1MB marker. I'm not restricting the size of the kernel anywhere, as far as I know.

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 2:50 pm
by smeezekitty
i see one big problem

Code: Select all


void kputch(const char chr)
{
   char* vramptr = (char*)0xB8000; <-- all chars will overwrite eachother
   
   *vramptr = chr;
   vramptr++;
   *vramptr = 0x7;
}


}
you have to make vramptr a global or atleast static.

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 4:12 pm
by Lithorien
smeezekitty wrote:i see one big problem

Code: Select all


void kputch(const char chr)
{
   char* vramptr = (char*)0xB8000; <-- all chars will overwrite eachother
   
   *vramptr = chr;
   vramptr++;
   *vramptr = 0x7;
}
}
you have to make vramptr a global or atleast static.
Well, right now, I'm just trying to get kprintf to work. Once I do that, I'll update the kputch code to keep track of where it is in memory. The code to do that is fairly trivial, since it'd just be more or less a copy and paste from my assembler code.

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 6:13 pm
by smeezekitty
try replacing kprintf with:

Code: Select all

void kprintf(const char* strptr)
{
unsigned i=0;
   while (*strptr != 0 && i < 65535) //make sure that an infinite loop is impossible if the string is not null terminated
   {
      kputch(*strptr);
      
      strptr++;
      i++;
   }
}

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 7:13 pm
by Lithorien
smeezekitty wrote:try replacing kprintf with:

Code: Select all

void kprintf(const char* strptr)
{
unsigned i=0;
   while (*strptr != 0 && i < 65535) //make sure that an infinite loop is impossible if the string is not null terminated
   {
      kputch(*strptr);
      
      strptr++;
      i++;
   }
}
Nice catch there - thank you very much. :) While it didn't solve the problem I'm having, it's always good to have a check to make sure I'm not trying to print forever. :)

Re: Calling kprintf makes kernel unbootable.

Posted: Tue Oct 27, 2009 7:25 pm
by pcmattman
then dropping that entire image into memory at the 1MB marker
Are you parsing the PE format and putting the sections at the right place? Or are you just dropping the full file contents at the 1 MB mark?

Re: Calling kprintf makes kernel unbootable.

Posted: Wed Oct 28, 2009 6:15 am
by Lithorien
pcmattman wrote:
then dropping that entire image into memory at the 1MB marker
Are you parsing the PE format and putting the sections at the right place? Or are you just dropping the full file contents at the 1 MB mark?
I was not parsing the PE format, just relying on the linker to put everything in the right place for me. I forgot about the file headers, which were a huge problem. So I stripped them out with 'objcopy -g -x -X -S -Obinary' and presto, it works just fine.

Thank you for pointing me to the right direction. :)