Autor Thema: Bootloader (in ASM) und Kernel (in C)  (Gelesen 5398 mal)

secure::1337

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« am: 06. August 2005, 11:40 »
:?:

Nunja, ich hab ein Problem. Vielleicht zu recht, oder ich kann nicht lesen. Auf jedenfall pack ich das nicht, einen Bootloader in Assembler zu schreiben und einen Kernel in C.

Deshalb, wünscht ich, dass mir einige Personen... Unterstützung geben könnten. Das heißt, ich würde gern, auch wenn es nur ein ganz billiger Bootloader ist... und auch ein ganz billiger Kernel ist, ein Beispiel haben...

Also, ich möchte nur einen Bootloader haben... und einen C-Kernel...
Die zusammen funktionieren. Zum Beispiel... Gibt der Bootloader nen String aus... und startet einfach nur die main()-funktion im C-Kernel. Die main()-Funktion muss auch nichts machen... sie kann Standart bleiben:

int main()
{
}

^^ Mehr muss sie nicht, sie soll nur gestartet werden.

(Ich hoffe ihr versteht mich, da ich mich meist ganz schön schwer tu', meine Probleme zu erklären...)

Also, ich hab das Komplette GCC. Auch DJGPP und
selbstverständlich auch NASM.

:?:

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. August 2005, 13:31 »
Wenn du einen Realmode Kernel haben möchtest wirst du dafür wohl GCC nicht verwenden können.

GCC geht von einem flachen Speichermodell aus und verwendet lineare Addressierung und keine Segment:Offset Addressierung.
Du musst also in den Protected Mode schalten oder einen anderen C Compiler verwenden. Ich würde dir empfehlen direkt den Umgang mit dem Protected Mode zu lernen anstatt erst ein Realmode OS zu coden.
Um in den Protectedmode zu schalten hast du 2 Möglichkeiten:
1.) Du schaltest im Bootloader in den Protected Mode, dazu muss der Bootloader aus 2 Teilen bestehen, da du in 512 Bytes nicht den Code unterbringen kannst, um in den Protected Mode zu schalten und einen Kernel zu laden. Du lädst also erst den 2. Teil des Bootloaders und schaltest dann im 2. Teil in den PM.
2.) Du schaltest am Anfang des Kernels in den PM. Das ist warscheinlich leichter zu coden, dafür nicht so flexibel. Du kannst dann z.B. nur das Binärformat für deinen Kernel benutzen, da 16 Bit Code von anderen Formaten nicht so gut unterstützt wird. Das Laden von Modulen wird auch schwerer, da man nicht weiß, wie groß die BSS Section ist usw.

Ich würde dir empfehlen als Bootloader für dein OS GRUB zu verwenden, da er einfach die besten Features hat. GRUB kann direkt einen C Kernel laden und du bist sofort im PM.

Ein Beispiel für einen C Kernel und das schalten in den PM findest du auf der Seite im Tutorial "C Kernel".

secure::1337

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. August 2005, 23:37 »
Okay, alles schön und gut... Aber mit dem Beispiel "C Kernel" kann ich nichts anfangen... hab mir ja ALLE PDF's gezogen. Aber irgendwie pack ich das nicht... Nur der Bootloader zeigt ne Message an... den Kernel läd er erst garnicht.. oder er funktioniert nicht so wie er soll. Deshalb hatte ich um ein Konkretes Beispiel geboten. Einen Bootloader der einen C Kernel läd und dann nichts tut als eine Message auszugeben... oder einfach nur die main() Funktion aufzurufen. Ich weiß, ich stell mich recht blöde an. Nunja, aber ist mir halt wichtig, dass ich das hinkriege. Oft ist es bei fast jeder Person so, dass man die Lust verliert, wenn man's nach dem 10ten Versuch noch immer nicht geschnallt hat, warum das jetzt nicht funktioniert. Ich mein alles schön und Gut. Trotz dessen würd' ich gern ein Beispiel haben. Bitte *bettel :)
Immerhin ist nicht jeder Tag dafür bekannt, das jemand sagt: "Ich will ein OS coden.". Nunja, ob ich das will ;) Ich weiß nur, dass ich das wissen haben möchte... und es können. Und wenn ich das nicht packe, leß ich noch'n 20tes mal. Aber irgendwann sollte es doch klappen. Oder :?:

hannibal

  • Host
  • Beiträge: 400
    • Profil anzeigen
    • brainsware - the rock.
Gespeichert
« Antwort #3 am: 07. August 2005, 01:22 »
lies dir mal das protected-mode tutorial von teejay durch, da ist das alles sehr gut beschrieben.

aber ich wuerde trotzdem den vorschlag mit grub in erwaegung ziehen, da das ganze dann weniger frustrierend ausfaellt :) schau dir mal die LOST-sources an, da wird grub verwendet.
\\o
o//
\o/

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #4 am: 07. August 2005, 11:43 »
Kann mich hier nur anschliessen - die bootsec.asm macht ihre Ausgabe - aber dann passiert nichts mehr...

interessant ist auch das das Tutorial nicht gleich dem Source von TeeJay ist...

z.b.: steht im Turorial für die Link.txt " .text 0x10200 : { " aber in den downloadbaren Files steht " .text 0x200 : { "

Kann hier uns jemand konkret weiterhelfen?

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 07. August 2005, 12:05 »
Das Textsegment muss natürlich dahin gelinkt werden, wo der Bootloader es hinlädt.
Ich glaube, TeeJay hat auf seiner Site auch einen Bootloader + Kernel der in den Protected Mode schaltet und einen C Kernel läd. Der müsste funktionieren.

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #6 am: 07. August 2005, 14:41 »
Alloa.

Es musst heissen 0x10200

Da ist mir wohl ein Fehler beim abtippen passiert.
----------------------
Redakteur bei LowLevel

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #7 am: 09. August 2005, 11:45 »
Hey cool... siehe da es funktioniert in BOCHS - ich kann es von Diskette in Bochs booten und alle Ausgaben funktionieren... Aber ich hab da noch ein Problemchen - wenn ich es direkte mit der Diskette boote (also ohne BOCHS) dann führt mein Computer zwar die Main aus restartet aber umgehend neu...

habe auch schon am Ende der main folgendes eingetraen:

void main()
{
  ...
  ...
  ...
  for (;;);
}


Wie kann ich dieses beheben?

Lg Stefan

hackgod

  • Beiträge: 70
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 09. August 2005, 12:40 »
hast du schon in die Log-Datei von BOCHS geschaut um auszuschliesen dass dein Kernel vielleicht doch irgendwie nicht richtig funktioniert?
also ich hab bei mir als letztes immer ein
while(1)
asm volatile ("nop");

stehen. Müsste aber mit deiner Version auch klappen

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #9 am: 09. August 2005, 18:46 »
Okay, jetzt bleibt der Kernel stehen... aber ich kriege noch immer keinen Output auf das Display...

folgendes ist meine Main:

int main()
{
  char *vidmem = (char*)0xB8000;
                                                                                                                           
  *vidmem = 'A';
  vidmem++;
                                                                                                                           
  *vidmem = 0x4F;
  vidmem++;
                                                                                                                           
  while(1)
   asm volatile ("nop");

  return 0;
}


Mach ich da was falsch?

matthieuriolo

  • Beiträge: 226
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 09. August 2005, 19:43 »
die farbe is falsch, sollte 0x007 lauten (glaube ich jedenfalls... oder so gehts jedenfalls bei mir  :lol: )

hackgod

  • Beiträge: 70
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 09. August 2005, 19:47 »
Also ich machs so:char *VideoMem = (char*)0xB8000;
unsigned int posx = 0;
unsigned int posy = 0;
void printf(char *_string, char _color)
{
int i;
for(i=0; _string[i] != '\0'; i++)
{
switch(_string[i])
{
case '\t':
posx = posx + 8;
break;
case '\n':
posx=0;
posy++;
break;
case '\b':
break;
default:
printc(_string[i], _color);
break;
}
}
};
void printc(char _character, char _color)
{
int pos = ((posy*80) + posx)*2;
VideoMem[pos] = (unsigned char) _character;
pos++;
VideoMem[pos] = (unsigned char) _color;
posx++;

if(posx >= 80)
{
posy++;
posx=0;
}
if(posy >= 25)
{
ClearScreen(0x70);
}
};
void ClearScreen(char _color)
{
int i;
for(i=0; i<=(80*25*2); i++)
{
VideoMem[i] = ' ';
i++;
VideoMem[i] = _color;



}
posx=0;
posy=0;
};
void SetCursor(int _posx, int _posy)
{
posx = _posx;
posy = _posy;
};

mit den Variablen posx und posy isses unter anderem auch leicht nen Zeilenumbruch oder einen Tabulator zu implentieren.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 09. August 2005, 20:50 »
Zitat von: woigl
Okay, jetzt bleibt der Kernel stehen... aber ich kriege noch immer keinen Output auf das Display...

folgendes ist meine Main:

int main()
{
  char *vidmem = (char*)0xB8000;
                                                                                                                           
  *vidmem = 'A';
  vidmem++;
                                                                                                                           
  *vidmem = 0x4F;
  vidmem++;
                                                                                                                           
  while(1)
   asm volatile ("nop");

  return 0;
}


Mach ich da was falsch?


ich kann keinen fehler entdecken. sicher, dass der kernel auch wirklich in der while schleife stehen bleibt?

vielleicht haben auch die selektoren eine falsche basis-adresse. ich glaube bei TeeJays Tutorial hatten die eine basis von 0x10000 (oder 0x10200?). probier mal statt 0xB8000 für vidmen 0xA8000 aus.

0x4F ist nicht falsch. einfach nur weiss auf rot. 0x07 ist hingegen grau auf schwarz und schaut langweiliger aus ;)
Dieser Text wird unter jedem Beitrag angezeigt.

woigl

  • Beiträge: 93
    • Profil anzeigen
    • http://www.nogos.org
Gespeichert
« Antwort #13 am: 09. August 2005, 21:31 »
ich habs auch mit 0xA000 und 0xB000 ausprobiert.

0xB000 funktioniert in BOCHS

0xA000 funktioniert niergends!!

hilfe... kann mir mal jemand seine files mailen die bei ihm funktionieren?? inkl. linker skript usw.?

Lg Stefan

 

Einloggen