Page 1 of 1

unable to pass arguments to putch()

Posted: Fri Oct 10, 2008 3:12 am
by combate
I have encountered a problem after having managed to load the kernel from the bootloader.

Now I am trying to write on the screen, however when i call the function puts() does not pass the string.

I have no idea of why does not work, someone can have a look and help me find the problem

this is my kmain.c

Code: Select all

void kmain(void)
{
   iniciarVideo();

   puts("hello");

   for (;;);
} 

this is my video.c

Code: Select all

void puts(char *str)
{
     int i;
   
     if(!str)
        return;

    for (i = 0; i < strlen(str) ; i++)
          putch(str[i]);
     
}
the function above does not work, however when I try with the function below, print fine

Code: Select all

void puts(char *str)
{
     int i;
     char bla[] = "HELLO WORLD";

     for (i = 0; i < strlen(bla) ; i++)
          putch(bla[i]);       
} 
im compiling the os with GCC 4.3.2 in windows with djgpp

this is my linker script

Code: Select all

SECTIONS
{
    .data :
    {
        data = .; _data = .; __data = .;
        *(.data*)
    }

    .rodata :
    {
       rodata = .; _rodata = .; __rodata = .;
       *(.rodata*)
    }

    .bss :
    {
        bss = .; _bss = .; __bss = .;
        *(.bss*)
    }

    end = .; _end = .; __end = .;
}
this is my kinit.asm

Code: Select all

[BITS 32]

GLOBAL start
start:
	mov	ax, 0x10
	mov	ds, ax
	mov	ss, ax
	mov	es, ax
	mov	esp, 90000

	extern _kmain
	call _kmain
	cli
	hl
And im linking with this command

Code: Select all

ld --oformat binary -Ttext 0x10000 -T linker.ld -o KERNEL.SYS kinit.o kmain.o video.o klib\opmem.o klib\string.o lib\ports.o 
any idea why isnt passing any arg? thanks for the help

Re: unable to pass arguments to putch()

Posted: Fri Oct 10, 2008 4:31 am
by CodeCat
I think your linker script is missing a rather important section: .text :P And you also need to define the entry point in the linker script: ENTRY(start) Secondly, if you're setting up a new stack, you MUST have interrupts disabled because otherwise an interrupt might happen before the stack is set up, and it'll go nuts (interrupts need a stack).

Aside from that, your puts function is a little inefficient, as it traverses the string twice (once for strlen, then again to print the chars). Try this:

Code: Select all

void puts(char *str)
{
	while (*str != 0)
	{
		putch(*str);
		++str;
	}
}

Re: unable to pass arguments to putch()

Posted: Fri Oct 10, 2008 6:17 am
by JamesM
CodeCat wrote:I think your linker script is missing a rather important section: .text :P And you also need to define the entry point in the linker script: ENTRY(start) Secondly, if you're setting up a new stack, you MUST have interrupts disabled because otherwise an interrupt might happen before the stack is set up, and it'll go nuts (interrupts need a stack).

Aside from that, your puts function is a little inefficient, as it traverses the string twice (once for strlen, then again to print the chars). Try this:

Code: Select all

void puts(char *str)
{
	while (*str != 0)
	{
		putch(*str);
		++str;
	}
}

Or...

Code: Select all

void puts(const char *str)
{
  while (*str)
    putch(*str++);
}
;)

Re: unable to pass arguments to putch()

Posted: Fri Oct 10, 2008 7:55 am
by CodeCat
Those two probably are the same in the underlying assembly anyway. And I prefer writing inc/dec statements separately, to improve code readability. Same with the != 0 thing.

Re: unable to pass arguments to putch()

Posted: Fri Oct 10, 2008 8:04 am
by Steve the Pirate
Not that it would make much of a difference, but puts should probably take a const char * argument instead of a char*. Because in newer versions of GCC, I beleive that if you have the argument as a char *, and then call puts("String"); then it will spit out an error like "Depreciated conversion from const char * to char *" or something.