Author |
Message |
Laurent
Joined: Mon Nov 09, 2009 2:14 pm Posts: 4 Location: The Netherlands
|
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
|
Mon Nov 09, 2009 2:20 pm |
|
|
AndyEsser
Joined: Mon Oct 26, 2009 2:33 pm Posts: 38 Location: United Kingdom
|
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()?
_________________ Andy Esser neogenix Broadcast
|
Mon Nov 09, 2009 4:56 pm |
|
|
Laurent
Joined: Mon Nov 09, 2009 2:14 pm Posts: 4 Location: The Netherlands
|
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(;;); }
|
Tue Nov 10, 2009 4:56 am |
|
|
AndyEsser
Joined: Mon Oct 26, 2009 2:33 pm Posts: 38 Location: United Kingdom
|
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.
_________________ Andy Esser neogenix Broadcast
|
Tue Nov 10, 2009 7:29 am |
|
|
Laurent
Joined: Mon Nov 09, 2009 2:14 pm Posts: 4 Location: The Netherlands
|
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.
|
Tue Nov 10, 2009 12:48 pm |
|
|
Laurent
Joined: Mon Nov 09, 2009 2:14 pm Posts: 4 Location: The Netherlands
|
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.asmCode: [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.ldCode: 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 ...
|
Tue Nov 10, 2009 2:21 pm |
|
|
Arlen
Joined: Sat Jan 16, 2010 7:53 pm Posts: 18 Location: Melbourne, Australia
|
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.
|
Sat Jan 16, 2010 8:23 pm |
|
|
xarnze
Joined: Wed Jan 06, 2010 2:38 pm Posts: 4
|
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); }
_________________ Vist my website - Germsoft.com Getting to ring 3 tutorial Forum
|
Thu Jan 21, 2010 6:32 pm |
|
|
Faust7011
Joined: Thu Feb 24, 2011 5:45 pm Posts: 2
|
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();
|
Thu Feb 24, 2011 5:54 pm |
|
|
brenden
Site Admin
Joined: Fri Jul 24, 2009 10:02 pm Posts: 247 Location: Las Vegas, NV, US
|
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?
|
Mon Mar 07, 2011 5:08 am |
|
|
Who is online |
Users browsing this forum: No registered users and 3 guests |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum
|
|