Bona Fide OS Development
http://forums.osdever.net/

Problem booting OS
http://forums.osdever.net/viewtopic.php?f=5&t=73
Page 1 of 2

Author:  Laurent [ Mon Nov 09, 2009 2:20 pm ]
Post subject:  Problem booting OS

I'm following the tutorial "Bran's Kernel Development tutorial" and I'm stuck. When I want to print a string on screen, GRUB gives an error. putch('A'); works perfect (prints the caracter), but puts("Hello World"); gives:
Code:
  Booting 'My Own Kernel'

root  (fd0)
 Filesystem type is fat, using whole disk
kernel /kernel.bin

Error 13: Invalid or unsupported executable format

Press any key to continue...

Even before my OS has started! And when I press any key I see the menu of GRUB again...

I'm using the following code:
Code:
void puts(char *str)
{
   int i;
   for (i = 0; i < 6; i++)
   {
      putch(str[i]); // Works, no need to post it here
   }
}

int strlen(const char *str)
{
   int r = 0;
   while (*str != '\0')
   {
      str++;
      r++;
   }
   return r;
}

void main()
{
   init_video(); // Works
   putch(strlen("Hello") + 'A');
   puts("Hello");

   for(;;);
}


Please, somebody help me :P

Author:  AndyEsser [ Mon Nov 09, 2009 4:56 pm ]
Post subject:  Re: Problem booting OS

What happens if you just try to do puts() with a single character? Does that work the same way as putch()?

Author:  Laurent [ Tue Nov 10, 2009 4:56 am ]
Post subject:  Re: Problem booting OS

AndyEsser wrote:
What happens if you just try to do puts() with a single character? Does that work the same way as putch()?


Well, my posted puts has a bug (it doesn't use the length of the string). But that's not the problem, strlen doesn't even work!

So putch(strlen("Hello") + 'A'); should print 'F'. But thát doesn't work.

This works:
Code:
int strlen(const char *str)
{
   int r = 0;
   while (*str != '\0')
   {
      str++;
      r++;
   }
   return r;
}

void puts(char *str)
{
   int i;
   for (i = 0; i < strlen(str); i++)
   {
      putch(str[i]);
   }
}

void main()
{
   char c[5];
   c[0] = 'H';
   c[1] = 'e';
   c[2] = 'l';
   c[3] = 'l';
   c[4] = 'o';
   
   init_video();
   puts(c);

   for(;;);
}


This doesn't work (but the tutorial says that this should work):
Code:
void main()
{
   init_video();
   puts("Hello");

   for(;;);
}

Author:  AndyEsser [ Tue Nov 10, 2009 7:29 am ]
Post subject:  Re: Problem booting OS

It seems that things with a loop in don't sit well. You may find that your compiler is trying to optimise out the loop as much as possible and this might not use legal code/syntax.

Check your compilers documentation about branching loops etc and see what it says, alternatively tell it to compile with no optimisations.

Author:  Laurent [ Tue Nov 10, 2009 12:48 pm ]
Post subject:  Re: Problem booting OS

AndyEsser wrote:
It seems that things with a loop in don't sit well. You may find that your compiler is trying to optimise out the loop as much as possible and this might not use legal code/syntax.

Check your compilers documentation about branching loops etc and see what it says, alternatively tell it to compile with no optimisations.


Yes, you're right. When I use the following code (no loops) it works correct:
Code:
int length(char *str, int r)
{
   if (*str == '\0')
   {
      return r;
   } else {
      return length(str+1, r+1);
   }
}

int strlen(const char *str)
{
   int r = 0;
   r = length(str, 0);
   return r;
}


But when I compile (using gcc) the original code (with the loop and the pointer inside the loop) using -O0 (that's a capital O and a zero) I still get the weird error.

Author:  Laurent [ Tue Nov 10, 2009 2:21 pm ]
Post subject:  Re: Problem booting OS

Hmm. When I use puts("Hello World"), my kernel grows to 1 meg. So maybe C is correct... The fault might be this.

But I still don't know how to fix it.

start.asm
Code:
[BITS 32]
global start
start:
   mov esp, _sys_stack
   jmp stublet

ALIGN 4
mboot:
   MULTIBOOT_PAGE_ALIGN equ 1<<0
   MULTIBOOT_MEMORY_INFO equ 1<<1
   MULTIBOOT_AOUT_KLUDGE equ 1<<16
   MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
   MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
   MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
   EXTERN code, bss, end

   dd MULTIBOOT_HEADER_MAGIC
   dd MULTIBOOT_HEADER_FLAGS
   dd MULTIBOOT_CHECKSUM
   
   dd mboot
   dd code
   dd bss
   dd end
   dd start

stublet:
   extern main
   call main
   cli
   hlt

SECTION .bss
   resb 8192
_sys_stack:


link.ld
Code:
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
   .text phys : AT(phys)
   {
      code = .;
      *(.text)
      . = ALIGN(4096);
   }

   .data : AT(phys + (data - code))
   {
      data = .;
      *(.data)
      . = ALIGN(4096);
   }

   .bss : AT(phys + (bss - code))
   {
      bss = .;
      *(.bss)
      . = ALIGN(4096);
   }
   end = .;
}


Have I done something wrong?

EDIT: Solved! I had to use nasm -f elf -o ... in stead of nasm -f aout -o ...

Author:  Arlen [ Sat Jan 16, 2010 8:23 pm ]
Post subject:  Re: Problem booting OS

Just an autopsy on what was happening here (and why):

Chars are just the same as numbers, in the end - just a different way of representing it. So, they don't need any special allocation in the resulting image after linking.

But, a string needs to be stored elsewhere - when you type puts("Blah blah, some string"), that string is allocated in a separate part of the image, since the call to puts is actually just passing a pointer to that string. (if there's a pointer, it has to point somewhere!)

So, introducing the first string in the program was causing nasm to create a new section of this kind of pre-initialised data, which maybe started at the 1MB mark in a COFF file. Who knows. :-)

Author:  xarnze [ Thu Jan 21, 2010 6:32 pm ]
Post subject:  Re: Problem booting OS

One of the problems with Brians tutorials is the linker script, use the one bellow it has a rodata section that will help to prevent errors in future.

Code:
ENTRY(start)
SECTIONS
{
  .text 0x100000 :
  {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }

  .data :
  {
     data = .; _data = .; __data = .;
     *(.data)
     *(.rodata*)
     . = ALIGN(4096);
  }

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

  end = .; _end = .; __end = .;
  . = ALIGN(4096);
}

Author:  Faust7011 [ Thu Feb 24, 2011 5:54 pm ]
Post subject:  Re: Problem booting OS

I have a problem that is similar to this one.

I am following Bran's tutorial, and I was having some weird errors while using char* pointers.
I checked everything, realised strlen wasnt working, etc. Added a .rodata section to my linker file.

And then the problem seem to appear everytime I use a loop, or a pointer, or both.

Ex. : I write
strlen(myPtr);
and *myPtr is always == '\0', so strlen always return 0.

Ex.2 : The code below only works until "HERE". After, string is equal to zero. Always.
( value displays HEX value of the char: value('R') = 0x52 )
Code:
int i;
i = 0;
value(string[i]);
putch(*(string+i));
printnl();
// HERE
for (i=0; i < 5; i++) {
   value(*(string+i));
}
printnl();

Author:  brenden [ Mon Mar 07, 2011 5:08 am ]
Post subject:  Re: Problem booting OS

Did everyone figure out their problems? Was it really the linker script? If so we can update that, but Bran tested everything, so maybe something changed with gcc or ld?

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