Lowlevel
Lowlevel => Softwareentwicklung => Thema gestartet von: mineorbit am 09. May 2013, 11:18
-
Hallo LowLevel Community,
Nachdem ich jeden Schritt eures Tutorials befolgt habe, hat alles geklappt.
Nur ab dem Paging tritt immer Exception 14 auf die ja mit dem Paging zusammenhängt.
Wie kann ich diesen Fehler verhindern. Über eine Antwort freue ich mich sehr.
(Entschuldigung falls ihr dieses Thema schon hattet!)
Mineorbit
-
Hallo,
Exception 14 ist #PF - Page Fault. Die hat verschiedenste Ursachen.
Um diesen "Fehler" zu verhindern, musst du erstmal rauskriegen, was diesen "Fehler" verursacht. (Page Faults sind übrigens nicht unbedingt Fehler, sondern können von Betriebssystemen gezielt eingesetzt werden.)
Gruß,
Svenska
-
Aha schon mal vielen Dank!
Kann Es damit zusammen hängen, dass er das Testprogramm(also Test.bin) nicht laden kann?
Wo speziell muss ich die test.bin ablegen(wie muss das Verzeichnis aufbauen)?
Mineorbit
EDIT:
Was meinst du genau mit Fehler in Zeile 42?
-
Fehler in Zeile 42.
-
Er meint damit, dass wir aus den kargen Informationen, die du uns gibst, nicht ableiten können, wo der Fehler liegen könnte. Für eine erste Idee, wo der Fehler liegen könnte, solltest du dir den Error Code anschauen, der beim Page Fault auf den Stack gelegt wird. (Siehe auch: http://www.lowlevel.eu/wiki/Exception#Page_Fault (http://www.lowlevel.eu/wiki/Exception#Page_Fault))
-
Und fast wichtiger noch eip und cr2 anschauen.
-
Also ich habe nachgeschaut und denke der Fehler ist
"*auf eine Page zugreift, die nicht aktiv ist (Present-Bit gelöscht)."
Weil er ja auf die test.bin zugreifen muss die ich nicht in dem Image eingeordnet wurde.
Wo genau muss ich die Test.bin hinlegen,wenn überhaupt.
Mein Verzeichnis ist so aufgebaut
*boot/grub/stage1s,tage2,Menu.lst
*kernel.bin
-
Dein Betriebssystem unterstützt höchstwahrscheinlich kein Dateisystem. Das heißt, in deinem Betriebssystem gibt es kein "test.bin". Alles spielt sich im RAM ab, auch der Page Fault.
Magst du uns wirklich nicht verraten, was "kernel.bin" und "test.bin" sind und wie du die lädst?
Schaue dir an, wo der Inhalt deiner Dateien im RAM hingeladen wird.
Schaue dir an, wie dein Mapping aussieht. Mit "info mem" und "info tlb" kannst du in der Qemu-Console sehen, was Qemu denkt.
Überlege dir, was du wohin gemappt hast, wo dein Code ausgeführt wird und wo er sich im RAM befindet.
Deine Fehlerbeschreibung ist unvollständig (und deine Vermutung höchstwahrscheinlich falsch). Wenn du alle diese Fragen beantwortet hast, können wir nochmal drüber nachdenken. Vermutlich wirst du deinen Code posten müssen.
edit: Ich mag normalerweise keine Hervorhebungen in Fettschrift, aber hier ist das eher angebracht.
Gruß,
Svenska
-
Also kernel.bin wird von grub geladen test.bin wird nicht aufgerufen.
kernel.bin und test.bin habe ich genau nach eurem tutorial gebaut.(So was sollte man eigentlich nicht machen aber ich hab mir das auch alles durch gelesen)
Qemu würde ich gerne nutzen, krieg ich aber nicht installiert(ubuntu12.10)
Ansonsten weiß ich nicht wie ich das geladene im Arbeitsspeicher finden kann.
Danke für eure hilfe mineorbit
-
Du musst deine test.bin schon mit GRUB laden, wenn du keinen Dateisystemtreiber und Floppytreiber hast.
Dazu musst du in deiner menu.lst einfach eintragen:
module /test.bin
und natürlich dann auch die test.bin auf das Image kopieren.
Dann lädt dir GRUB die test.bin in den RAM.
Wo genau die dann liegt erfährst du mittels multiboot.
Mehr dazu steht hier: http://www.lowlevel.eu/wiki/Multiboot (http://www.lowlevel.eu/wiki/Multiboot)
-
Danke, dass habe ich total vergessen :grin:
Naja aber gibt nachwie vor Exception 14 aus.
Ich hab entdeckt das man im tutorial alles downloaden kann.
Hab die makefile gestartet und alles reingezogen und dort tritt auch Exception14 auf.
(Ich hoffe ich mache euch keine Umstände!)
Mineorbit
-
Mappst du das Prozessimage denn auch mit dem Userflag? Ansonsten löst die CPU die Exception aus, weil der Task im Usermode laufen soll und die Seiten so gemappt sind, dass nur Kernelmode-Code darauf zugreifen darf. Das Problem und eine sehr provisorische Lösung wird im Tutorial (http://www.lowlevel.eu/wiki/Teil_9_-_Paging) beschrieben (kurz vor "Aufteilung des Adressraums").
-
vielen Dank, dass scheint tazächlich der fehler zu sein!
Nur wie Mappe ich die vier 4Mb um?
Danke für die vielen Antworten,
Mineorbit
-
Das entspricht aber nicht dem Fehlercode, den du oben genannt hast (page not present).
-
Das entspricht aber nicht dem Fehlercode, den du oben genannt hast (page not present).
Naja jetzt habe ich die Page ja in den Ram geladen.Nur irgendwie findet er sie nicht.
Mineorbit
-
Wohin in den RAM lädst du denn die Page? An der Stelle ist sie dann auch.
Du brauchst die Page weder suchen noch finden, weil du vom GRUB gesagt bekommst, welches Modul er an welche Stelle geladen hat. Und diesen Bereich (von "Adresse" bis "Adresse + Größe", aufgerundet auf PAGESIZE) musst du passend mappen.
-
Welchen genauen befehl muss ich eingeben, damit mir grub das sagt?
(Könnte man das Paging Problem nicht so lösen, dass ein Manager den Prozessen eine Zeit einteilt um auf die Resourcen zuzugreifen und die zeit von einer Pit abgezähltwird(Korigiert mich bitte wenn das vollkommener Schwachsinn ist :arrow: ))
Mineorbit
-
Da brauchst du keinen Befehl, es reicht wenn du die multiboot_info_t Struktur ausliest. Wenn du deinen Kernel mit Grub bootest, findest du wenn Grub die Kontrolle an dich abgibt in eax eine Magic-Number (sollte 0x2BADB002 sein). Diese validiert den Zeiger auf die multiboot_info_t Struktur, zu finden in ebx.
Gruß,
Streetrunner
-
Wie genau gibt man eax und ebx aus?Wenn müsste das dann doch in start.S?Langsam wird's echt schwierig!
(Gibt es eine Anleitung?)
mineorbit
-
(Gibt es eine Anleitung?)
Ja gíbt es, z.B. hier (zwar auf Englisch aber egal):
http://wiki.osdev.org/Bare_Bones
Da kannst du sehen das in der "loader"-Funktion die Register eax auf die globale Variable "Magic" und ebx auf die globale Variable "mbd" geschrieben werden.
In "kmain" werden diese Variablen dann einfach verwendet.
Du kannst aber auch direkt zu Beginn deiner start.S, also direkt nach dem Multiboot-Header, die beiden Register auf den Stack schieben. Das sähe dann ungefähr so aus:
.section multiboot
#define MB_MAGIC 0x1badb002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
.align 4
.int MB_MAGIC
.int MB_FLAGS
.int MB_CHECKSUM
.section .text
.extern Main
.global _start
_start:
mov $kernel_stack, %esp
pushl %eax ; eax auf den Stack schieben
pushl %ebx ; und ebx auch
call Main
Die passende Funktion "Main" sieht dann etwa so aus:
void Main (void* mbt, uint32_t Magic)
{
...
}
Gruß,
Streetrunner
-
:grin: Ich glaube diesmal hats funktioniert!
Er hat mir nichtmehr die Exception ausgegeben sondern:01234
Hoffentlich sollte doch das dabei rauskommen?
Falls es das gewesen ist bin ich euch was schuldig!
-
Hallo,
Könnte man das Paging Problem nicht so lösen, dass ein Manager den Prozessen eine Zeit einteilt um auf die Resourcen zuzugreifen und die zeit von einer Pit abgezähltwird (Korigiert mich bitte wenn das vollkommener Schwachsinn ist)
Es ist eine ziemlich dumme Idee, einem Programm mitten in der Arbeit den RAM abzuklemmen. :evil: Der Sinn von Paging liegt darin, dass du verschiedenen Programmen gleichzeitig verschiedene Teile vom RAM zuteilen kannst, ohne, dass die Programme davon etwas mitbekommen.
Es wird also nicht nach der Zeit, sondern nach den Ressourcen zugewiesen. Verantwortlich dafür ist der VMM (Virtual Memory Manager), ein Hauptbestandteil aller modernen Betriebssysteme.
Ansonsten würde ich sagen, fehlen dir ein paar Grundlagen, wie das mit dem Paging und so funktionieren soll. Lies dich da mal etwas ein, dann wird das auch viel klarer, warum man sowas macht (und warum das überhaupt eine gute Idee ist). Und dann sind die Tutorials auch weniger ein "ich muss das hier so schreiben" und mehr ein "aha, so funktioniert das also". :-D
Gruß,
Svenska
-
Danke das du mich korrigiert hast, Svenska!
Ja, ich rede ziemlich viel Schwachsinn aber ich muss mich noch sehr weit ins Thema einarbeiten.
Ich hätte noch eine Frage:Kann ich im test.bin im 3.Ring auf Funktionen des kernels, wie kprintf zugreifen,und wenn wie?
Vielen Dank für die Hilfe!
-
Nein, kannst du nicht. :-P (schade aber auch :wink:)
Deine test.bin ist ja als extra elf gelinkt und nicht im kernel.
Du muss alle Funktionen, die dein Kernel den Programmen zur Verfügung stelle soll, über Syscalls anbieten
-
Hat sich schon erledigt! Hab gerade gemerktdas das falsch war.
:lol:
Edit:Wie würde man den einen solchen Systemcall machen?
-
Es gibt verschiedene Möglichkeiten. Die einfachste(die auch in unserem tollen Tutorial(http://www.lowlevel.eu/wiki/Teil_6_-_Multitasking) angesprochen wird ist die Realisierung als soft-Interrupts).
Das heißt du registrierst einen neuen Interrupt-handler (bei Linux bspw. für Interrupt 0x80).
Diesen Interrupt kannst du nun vom Userspace mit asm volatile ("int $0x80");
oder sowas auffrufen.
Damit dein Syscall-Handler auch weiß, dass der print syscall gemeint ist empfiehlt es sich vorher ein Interrupt-nummer nach (z.B) EAX zu verschieben und ein pointer auf den zu printenden String kann man vorher (z.B) nach EDX verschieben.
-
Vielen Dank!
Das hätte sich dann auch erledigt!
Wie schließe ich diesen Thread?
Vielen Dank nocheinmal!
Mineorbit