Autor Thema: GRUB und C Kernel Problem  (Gelesen 7446 mal)

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« am: 24. August 2007, 21:14 »
Hallo zusammen,
nachdem ich wieder Interesse an OS developing habe, wollte ich wider mal anfangen zu coden. Auf www.osdever.net ist ein Tutorial, "a simple C kernel" so.
Jedenfalls habe ich den start.asm verstanden und kann ohne zu gucken coden:


;   Blackout 2007 (OS)
;   Copyright (C) 2007  Ercan Akyürek
;   
;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.
;   
;   This program is distributed in the hope that it will be useful,
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.
;   
;   You should have received a copy of the GNU General Public License
;   along with this program.  If not, see <http://www.gnu.org/licenses/>.


[BITS 32]
global start
start:
mov esp, _sys_stack ; pointing to our new stack area
jmp stublet

; We had to align 4 byte
ALIGN 4

mboot:
; Multiboot header for GRUB
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

; Here comes the boot signature for grub
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM

; the linker script will fill these datas
dd mboot
dd code
dd bss
dd end
dd start

stublet:
  extern main
  call main
jmp $

; GTD
; IRSs

SECTION .bss
; reserve 8kb (8192byte) of memory here
resb 8192
_sys_stack:


so dieses code kompilimiere ich mit:

nasm -f aout -o start.o start.asm

und bindes es so :

ld -T link.ld -o kernel.bin start.o

mit diesem linker script:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

so, mit dem hexeditor öffne ich den kernel, und da ist der multiboot header...

jetzt mache ich eine datei namens main.c, implementiere zum testen eine strlen:

size_t strlen(const char* string) {
  int len=0;
  while(string[len]!='\0') len++;
  return len;
}

void main()
{
    /* You would add commands after here */
char *test= "hi";
  int len = strlen(test);

}

dies komplimiere ich so:

gcc -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I./include -c -o main.o main.c

und binde es wie oben:


ld -T link.ld -o kernel.bin start.o main.o

okay, jetzt das ganze im hex editor angeschaut: nein, kein multiboot header, sondern nur die variabel "hi" und lauter 0er, 1MB lang..., und meine theorie bestätigt sich:

GRUB sagt: not executable format... oder so, jedoch, lösche ich den callback strlen:

size_t strlen(const char* string) {
  int len=0;
  while(string[len]!='\0') len++;
  return len;
}

void main()
{
    /* You would add commands after here */
char *test= "hi";

}

geht es auf einmal, da ist auch ein multiboot header da.

Ich arbeite unter gcc-Version 4.1.2 (Ubuntu 4.1.2-0ubuntu4)

woran KÖNNTE es leigen? ps: hab auf google etwas geschaut, auch hier, doch nicht BRAUCHBARES gefunden :(

Mfg Ercan

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #1 am: 24. August 2007, 23:24 »
Moin

Ich habe im Moment gerade keine Zeit mir dein Linkerskript genau anzuschauen. Aber ich würde dir empfehlen, mal ein einfacheres Linkerskript zu benutzen.

Sowas hier:
1 /**
 2  * Permission is granted to use, modify, and / or redistribute at will.
 3  *
 4  * This includes removing authorship notices, re-use of code parts in
 5  * other software (with or without giving credit), and / or creating a
 6  * commercial product based on it.
 7  *
 8  * This software is provided as-is. Use it at your own risk. There is
 9  * no warranty whatsoever, neither expressed nor implied, and by using
10  * this software you accept that the author(s) shall not be held liable
11  * for any loss of data, loss of service, or other damages, be they
12  * incidental or consequential. Your only option other than accepting
13  * this is not to use the software at all.
14  */
15
16 ENTRY(start)
17 OUTPUT_FORMAT(elf32-i386)
18
19 SECTIONS
20 {
21     . = 0x100000;
22     .text :
23     {
24         *(.text)
25     }
26
27     .data :
28     {
29         *(.data)
30         *(.rodata)
31     }
32
33     .bss :
34     {
35         *(.bss)
36     }
37 }
Das stammt aus einem Beispielkernel für Grub von mir. Falls du Interesse daran hast, melde dich, dann mache ich das Ding nochmal soweit bereit, dass ich es rausgeben kann.

Aber noch zu deinem Code: Ich suche noch nach dem sinn deines C-Codes. ;-) Wie wärs denn mal mit einem einfachen Hello World auf dem Bildschirm?
Auch das void main() gefällt mir nicht, da das nicht konform zur aktuellen C-Spezifikation ist.

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 25. August 2007, 10:45 »
Mein C-Code hat kein Sinn, ich probiere es nur aus, weil ich habe auch versucht  einen String auf dem Video Speicher zu schreiben, gleiches Ergebnis. Ich wollte nut mit dem Code verdeutlichen, das wenn ich ich eine Funktion, oder ähnliches verwende, geht nichts... Also zur Code: Da ich Tage lang am verzweifeln war, habe ich schnell mal ein Test C Code geschreiben...

Nun zum linkerscript:
Beim erset versuch gab es beim linken ein Fehler, undefined referece to 'bss, end, code'
Aber danach habe ich das ganze etwas geändert:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

und jetzt klappt es ;)

Aber wieso kapiere ich nicht sooo ganz, naja danke ;)

Mfg Ercan

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 25. August 2007, 10:58 »
oh sorry, hab falsches Kernel geladen :/( es geht doch nicht....

Mfg Ercan

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #4 am: 25. August 2007, 11:34 »
Hast du ein x86-64 System?
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 25. August 2007, 11:37 »
Wie jetzt? Emu oder mein PC ^^
Nein keine x86-64 system... Wieso denn?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #6 am: 25. August 2007, 11:58 »
Ich hab mal versucht das ganze zu reproduzieren. Da ich ein x86-64 System hab war ne kleinere Änderung am Linkerscript und ein bisschen was am Makefile nötig. Ich habs dann mit mbchk auf die Multibootheader überprüft, das hat soweit funktioniert. Danach hab ich es versucht mit Grub zu laden. Das ging auch glatt. Hab dir mal ein tar-Archiv mit den Source- & Objektdateien, einem Makefile, dem Linkerscript und der kernel.bin per eMail geschickt.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 25. August 2007, 12:07 »
Hey, vielen dank an dich ;) Es funktioniert...
ich schau mal was ich bei mir falsch gemacht habe...

Mfg Ercan

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #8 am: 25. August 2007, 12:09 »
Würd mich dann auch interessieren. :wink:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 25. August 2007, 12:13 »
hey, das war ja ein fehler von 4 zeichen:

nasm -f aout -o start.o start.asm

muss

nasm -f elf -o start.o start.asm

heißen...
Das hast du ja in deinen makefile geschrieben...

immer diese Kleinigkeiten... Aber ich wundere mich trotzdem... in jedem tutorial heißt es aout....

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 25. August 2007, 15:08 »
Mit a.out sollte es eigentlich auch gehen, aber wieso sollte man sich die Mühe machen, wenn es mit ELF viel einfacher geht?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #11 am: 25. August 2007, 16:27 »
Ich kann mir schon vorstellen, dass ld ein bisschen durcheinander kommt wenn er ne aout mit ner elf zu ner binary machen soll :-)
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

geforcefan

  • Beiträge: 9
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 25. August 2007, 16:43 »
Okay, jetzt stehe ich vor ein neues Problem:

Ich habe laut dem Tutorial IDT, GTD, ISR, IRQ programmiert, geht eigentlich auch, aber sobald ich mein Keyboard benutzen will, wird auf dem Bildschirm eine S geschrieben, und hinten dran steht: General Protection Fault Exception. System Halted!

ich suche grad mein fehler, aber finde ihn nicht.


void keyboard_handler(struct regs *r)
{
    unsigned char scancode;

    scancode = inportb(0x60);

    if (scancode & 0x80)
    {
    }
    else
    {
        putch(kbdus[scancode]);
    }
}

void keyboard_install()
{
    irq_install_handler(1, keyboard_handler);
}
int main() {
...
keyboard_install();
...
}

woran könnte es nun liegen?
« Letzte Änderung: 25. August 2007, 16:47 von geforcefan »

FreakyPenguin

  • Administrator
  • Beiträge: 301
    • Profil anzeigen
    • toni.famkaufmann.info
Gespeichert
« Antwort #13 am: 25. August 2007, 19:26 »
Das kann viele Ursachen haben. Am besten änderst du mal deine Exception-Handler so ab, dass sie mindestens noch den EIP ausgeben. Das kannst du machen indem du am anfang der ISR (in Assembler) den Stackpointer abspeicherst und den Stackinhalt ausgibst. Eine Alternative wäre es direkt am Anfang der GPF-ISR ein hlt zu machen, und dir den Stack mit einem Debuger wie er in Bochs drin ist anzuschauen. Weiter könntest du auch qemu mit dem parameter -d int starten und dir danach die Logs ansehen.

 

Einloggen