Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - Savatage

Seiten: [1] 2
1
Lowlevel-Coding / Re: Ablauf Paging
« am: 17. November 2016, 07:49 »
Vielen Dank für eure wertvollen Tipps. Im Moment habe ich noch Sorgen mit der ... sagen wir ... Projektorganisation. Ich hoffe sehr, dass ich bald weiter entwickeln kann.

Ich melde mich baldmöglichst wieder!
Sava
2
Lowlevel-Coding / Re: Ablauf Paging
« am: 08. November 2016, 19:55 »
Das erste Problem konnte ich lösen: Die Paging-Initialisierung sollte sicher auch erst nach der Initialisierung der gdt stattfinden. Aber das neue Verhalten verstehe ich noch weniger.

Der Reboot verhält sich bei jedem Starten an. Ich habe mir zum Testen einfach mal ein kprintf in die Funktion gepackt, die eine PT mappt. Ergebnis ist, das unterschiedlich oft der Reboot durchgeführt wird und dann werden unterschiedlich viele PT gemappt. Also scheint es schon mal kein grundsätzliches Problem zu geben, da das mappen ja schon mal funktioniert.

Außerdem habe ich noch ein Problem bzgl. der Tasks. Diese laufen bisher nur mit phys. Adressen. Wenn ich also die vmm_init() auskommentiere laufen meine Task wieder. In diesem Zustand funktioniert auch mein Tastaturtreiber, der ebenfalls Bestandteil von meinem Kernel ist. Wenn ich jetzt aber die Initialisierung der Tasks, bzw. die Initialisierung des Multitasking auch auskommentiere funktioniert mein Tastaturtreiber auch nicht mehr. Es werden also keine Interrupts mehr ausgelöst. Ähnliches gilt dann, wenn das mappen der PT funktioniert hat und mein Kernel sich nicht ständig neustartet.

Ich hoffe ich konnte das jetzt verständlich formulieren. Das Paging bringt mich wirklich an den Rand des Wahnsinns. Ich überlege echt ob ich's sein lasse.
3
Lowlevel-Coding / Re: Ablauf Paging
« am: 05. November 2016, 08:27 »
Zitat
Das ist doch die ganz normale Meldung, die bei jedem Bootvorgang kommt?
Achso? Ich sehe das nie. Dann ist also jetzt das Problem dass er immer wieder neu bootet. Das ist schon mal gut zu wissen. Weißt du durch was ein Reboot ausgelöst wird? Bewusst diesen Befehl eingefügt habe ich zumindest nicht.

Spontan hätte ich vermutet dass er nicht in die Endlosschleife am Ende der Initialisierung kommt und deswegen neu startet. Macht Qemu sowas? Das würde aber bedeuten, dass während meiner vmm_init() irgendetwas schief läuft aber nicht mit ner Exception beendet wird. hm.....
4
Lowlevel-Coding / Re: Ablauf Paging
« am: 04. November 2016, 19:11 »
ok, hast du eine Idee was die Meldung im Bild bedeuten konnte, bzw. was das Verhalten erklärt?
5
Lowlevel-Coding / Re: Ablauf Paging
« am: 04. November 2016, 10:10 »
Das mit der Funktion ist natürlich ein Trick der nicht sofort ersichtlich ist. Aber danke für die Erklärung. Ich kann verstehen warum ihr das umgebaut habt.

Ich habe jetzt tatsächlich alle Fehler raus und mein Kernel kompiliert. Mit Qemu startet der Kernel erst und scheint dann aber etwas seltsames zu machen (siehe Anhang). Nach diesem Bild startet er sich neu... in Endlosschleife.
Ich habe jetzt noch nicht gedebuggt weil ich nicht weiß ob das nicht so seien muss, schließlich lasse ich ja auch Tasks laufen die noch keine virt. Adresse kriegen, sondern nur auf der phys. Adresse arbeiten.
Wenn ich den Teil auskommentiere der die Tasks initialisiert, scheint mein Kernel irgendwo "festzustecken". Wo genau und warum habe ich auch noch nicht durchschaut.

Mein weiteres Vorgehen wäre jetzt die Task's richtig einzubinden und erst wenn das kompiliert weiter nach Fehlern suchen. Macht das Sinn?

6
Lowlevel-Coding / Re: Ablauf Paging
« am: 03. November 2016, 13:15 »
Zitat
Übrigens, wenn du dich von tyndur inspirieren lassen willst, würde ich dir empfehlen eher kernel2 als kernel anzuschauen. Wir haben mit der Zeit auch das eine oder andere dazugelernt. ;)
Du bist ja witzig, da ist ja alles anders  :| Da werde ich wohl noch mal von vorn anfangen und mich da durch kämpfen.

Zitat
aber so ist kernel_page_tables einfach das gleiche wie kernel_page_directory.
Sowas wollte ich hören! Das klingt machbar.

Zitat
Das heißt, du willst nicht den (nicht existenten) Inhalt der Variable, sondern die Adresse von diesem Symbol haben: &kernel_start
An welcher Stelle holt sich tyndur die Adresse? Eine Dereferenzierung habe ich wohl irgendwo überlesen.

So, mit den Änderungen sind es schon deutlich weniger Fehler. Wenn ich es jetzt tatsächlich zum kompilieren bringe müsste mein Kernel doch auch eigentlich starten und laufen. Knallen tut es erst wenn ich Tasks laufen lasse. Aber solange er keine Tasks hat dürfte doch alle prima sein oder?
7
Lowlevel-Coding / Re: Ablauf Paging
« am: 03. November 2016, 12:15 »
ich habe jetzt den ersten Abschnitt - die Initialisierung vom Paging, programmiert. (oder besser: es versucht)
Dabei habe ich mich sehr an das tyndur Projekt gehalten. Ich bitte das nicht als abschreiben zu verstehen, sondern als verstehen wollen.

Nach dem ersten Kompilieren habe ich nun etliche Fehler:

1)
#define kernel_page_tables  ((uint32_t*)(kernel_page_directory + (KERNEL_BASE >> PGDIR_SHIFT)))
Diese Zeile gibt mir die Variable kernel_page_tables  an die Hand, die ich dann später den jeweiligen Tasks übergeben kann, bzw. in das Task PD mappen kann. Im Detail kann ich mit der Zeile wenig anfangen, würde sie aber gern verstehen.

2)
Ich habe aus dem Linkerskript Variablen für Anfang und Ende vom Kernel. Ebenso habe ich das jetzt für die Phys. Adresse vom Kernel. Die brauche ich ja um den Kernel in die PT zu mappen. Mit:
extern const void kernel_starthole ich mir die Variablen dann in den Code. Beim Verwenden erhalte ich dann aber die Meldung "incomplete type".  Oder anders gefragt wie kriege ich die Variablen in virtuelle und physische Adressen? Ein
(paddr_t) kernel_phys_startbringt nicht das erhoffte Ergebnis.

Ein paar weitere Fehler habe ich noch, aber an denen versuche ich mich noch ein bisschen selbst.
8
Lowlevel-Coding / Ablauf Paging
« am: 24. October 2016, 08:55 »
Wie auch so viele andere im Forum macht mich das Paging ganz schön fertig. Bevor ich nun anfangen kann mein Paging umzusetzen, versuche ich mir eine Art Programmablaufplan zu erstellen, damit ich weiß ob ich alles bedacht habe. Ich würde hier gern darstellen wie ich mir das ganze vorgestellt habe um dann zu erfahren ob das grundsätzlich richtig ist oder ob doch noch irgendwo Verständnisprobleme sitzen.

Allgemein:
- Ausgangssituation: Adressraum ist in 4kB Speicherblöcke als physische Speicher eingeteilt, verwaltet durch eine Bitmap (halt wie im Tutorial)
- Paging soll wie im Tutorial unterteilt sein in PD und PT
- Jeder Prozess mit eignem PD, Kernel wird immer rein gemappt
- Adressraumaufteilung 0-1 GB für den Kernel, 1-4 GB für den Userspace

So, zur Adressraumaufteilung gleich meine erste Frage: Das wird nur realisiert durch entsprechend gesetzte Flags in den PTE's?

Ablauf:
1. Initialisierung des Paging (läuft einmalig bei Kernelstart):
- Speicherkontext anlegen
- Danach werden im Tutorial die ersten 4 MB an dieselbe physische wie virtuelle Adresse gemappen. Das widerspricht der Adressaufteilung von 0-1 Kernel und 1-4 Userspace. Also kommt an diese Stelle das Mapping des Kernels (+ Videospeicher, + Bitmap)
- Speicherkontext aktivieren
- Paging aktivieren

2. Speicherverwaltung (läuft immer wenn ein neuer Task startet):
- Neues PD anlegen und dem Task mitgeben
- Kernel in das PD mappen
- Kontextwechsel beim Start des neuen Task im Interrupthandler

Sozusagen habe ich nur die 2 Funktion + etliche Hilfsfunktionen.

So weit, so kompliziert. Sobald mein Paging aktiviert ist, habe ich nur noch virtuelle Adressen. Um dennoch an die PD ranzukommen habe ich schon mehrfach gelesen dass das PD einen Eintrag auf dich selbst bekommt und ich es sozusagen als zusätzliches PT verwalten kann. Damit komme ich an die phys. Adresse, die ich ja zum aktivieren des PD brauche.

Jetzt noch eine offene Frage:
Wenn mein Task beendet ist wird ja der Speicherkontext gewechselt. Was passiert mit dem alten Kontext? Gilt der als unbenutzt und kann einfach wieder neu belegt werden?

Ich bin unsicher ob noch ein Thread zum Thema Paging wirklich was hilft, aber ich bin doch etwas ratlos und freue mich über alle Kommentare, Anregungen und Einschätzungen

Eure Sava


 

9
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 21. September 2016, 09:46 »
ich Esel... Einfach ignorieren... hatte tatsächlich noch zum debuggen ein t\n ausgegeben. Kaum nimmt man es raus, schon funktionierts.

trotzdem sehr hilfreich sich dem asm Befehl mal genau anzusehen.
10
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 21. September 2016, 09:39 »
ah, ok! Vielen Dank.
Wenn ich
asm("int $0x30" : : "a" (0), "b" ('0' + 3));ausführe steht in ebx: 00000033
Führe ich hingegen
asm("int $0x30" : : "a" (0), "b" (3));aus steht in ebx: 00000003

Also steht im 2. Byte von ebx immer noch eine 3 - sozusagen als Abfall.

Meine Ausgabe (kprintf("%c", cpu->ebx)) im ersten Fall ist:
t
3t
3t
...
oder (kprintf("%d", cpu->ebx)):
t
51t
51t
...


im Zweiten Fall
t
 t
 t
...


Die 51 passt ja schon mal weil 33h = 51d. Trotzdem verstehe ich nicht wo das t herkommt.

11
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 21. September 2016, 08:51 »
ich habe mittels qemu -d int geschaut was jeweils zum Syscall Aufruf in ebx drin steht.
ich dachte der erste Parameter im asm Befehl wird in eax geschrieben ( die 0 ) und der zweite in ebx?
Was genau meinst du mit bl?

Ich  glaube so langsam fällt es auf, dass ich nicht 100% verstanden habe wie der asm Befehl funktioniert. Ich werde mich mal schlau machen und hoffe dabei auf die Lösung zu stoßen. 
12
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 20. September 2016, 08:41 »
ich kriege das Problem mit dem zusätzlichen t in der Ausgabe nicht gelöst. Das Register ebx ist korrekt gefüllt und ist doch eigentlich nichts anderes als ein Hex-wert.
13
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 16. September 2016, 09:12 »
Problem gelöst.
Die For-Schleife war nicht richtig, sodass der Code nicht ausgeführt wurde.
Allerdings bin ich mit der Ausgabe noch nicht so recht zufrieden. Das ist die Schleife:
int i;
for (i = 0; i < 5; i++) {
asm("int $0x30" : : "a" (0), "b" ('0' + i));
}

Also erwarte ich als Ausgabe: 01234
Die tatsächliche Ausgabe ist aber:
t
0t
1t
2t
3t
4t

Nach jedem Syscall kommt irgendwo hier noch ein t und ein \n.
Es scheint wohl dass mein Konsolentreiber noch nicht ganz rund läuft. Da schau ich jetzt noch mal drüber.

Danke bisher erstmal.
14
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 12. September 2016, 18:38 »
Wie immer danke für die schnelle Antwort.

Zitat
Wenn du gar kein Anzeichen für irgendeinen Interrupt oder eine Exception siehst, dann würde ich behaupten, dass der Code gar nicht erst ausgeführt wird.
Das bestätigt mich immerhin das meine Interruptabhandlung funktioniert und ich da nicht weiter suchen brauche.

Zitat
Wenn du allerdings die ganze Zeit im Interrupthandler bleibst, könnte es natürlich passieren, dass der unterbrochene Code nie fortgesetzt wird. Halte ich für unwahrscheinlich.
Dies halte ich auch für unwahrscheinlich, weil meine Tastatureingaben reagieren und der entsprechende Interrupt für einen Tastenanschlag ausgeführt wird.

Zitat
Wenn das das Problem ist, könnte ein asm volatile helfen.
Ein asm volatile ändert leider gar nichts. Das wäre natürlich schön einfach gewesen :)

Zitat
Ansonsten qemu -d int und genau anschauen, welche Funktionen jeweils vom PIT-Interrupt unterbrochen werden und ob das die Stellen sind, von denen du erwartest, dass sie gerade laufen.
qemu -d int zeigt mir die Kernel Register und gefühlt 1000 andere Dinge? Das habe ich noch nie benutzt und muss mich da erst mal durch kämpfen. Wenn ich diesbezüglich weitere Infos habe, melde ich mich wieder. Bis dahin bin ich über weitere Tipps dankbar.

Gruß
Sava
15
Lowlevel-Coding / Syscall wird nicht aufgerufen
« am: 12. September 2016, 10:03 »
Hallo Team,

ich schaffe es einfach nicht einen Syscall von einem externen Programm auszulösen.
Die Initialisierung über Interrupt 48 sollte vollständig sein. In meinem Interrupt Handler fange ich den Syscall ab und leite ihn an die eigentliche Syscall Funktion weiter. Ich habe zunächst einen Syscall von einem externen Programm ausgelöst, und weil das nicht geklappt hat versuche ich nun von meiner init-Funktion des Kernels, nach der Initialisierung einen Syscall auszulösen:

asm("int $0x30" : : "a" (0), "b" ('0' + 1));
Das sollte ja einfach nur eine 1 ausgeben.
Zum Test habe ich mir im Interrupt-Handler mal ausgegeben welche Interrupts ausgelöst werden. Interrupt 0x30 ist jedoch nicht dabei. Es wird nur ständig der PIT (0x20) ausgelöst.

Kann es sein, dass der PIT sooft ausgelöst wird, das mein Syscall gar keine Chance hat an die Reihe zukommen? Ich habe dafür testweise den Syscall-Aufruf in der init-Funktion in eine Whileschleife gepackt um ihn immer wieder auszulösen. Allerdings wird der Syscall immer noch nicht ausgeführt.
Ich schaue jetzt noch mal die ganze Interrupt Initialisierung durch, weil doch eigentlich nur dort der Fehler sein kann, oder?

Gruß
Sava
16
Vielen Dank für die Hinweise. Du hast genau das Problem getroffen und mir sehr geholfen.

Effektiv war es nur ein Tippfehler. In der Initialisierung der PMM habe ich beim Durchlaufen der Adressen while (addr > addr_end) statt while(addr < addr_end) geschrieben. Super dämlich, aber beim debuggen lernt man mindestens genau soviel wie beim eigentlichen programmieren :)

Das Intel Manual ist gespeichert und wird ab jetzt zu Rate gezogen bevor ich eine neue Frage an die Community stelle.

Noch einmal besten Dank und bis zur nächsten Frage.
17
Lowlevel-Coding / physische Speicherverwaltung - Excpetion 5
« am: 16. August 2016, 10:19 »
Hallo OS-Dev Team :)

Ich kämpfe im Moment mit dem Tutorial Teil 7.  Dabei habe ich mich weitestgehend an Tyndur orientiert. Ich habe die physische Speicherverwaltung umgesetzt, aber noch 2 statische Tasks (im Usermode) in ein Array geschrieben (noch keine Liste). Die Task wechseln sich ganz klassisch über den Interrupt ab.

Ohne Speicherverwaltung klappt alles prima. Mit Speicherverwaltung wird nur noch ein Task ausgeführt und irgendwann tritt eine Exception 5 auf. Das sieht für mich erstmal nach einem Problem mit den Interrupts aus, an denen ich für die Speicherverwaltung ja aber nichts geändert habe. Von dem her bin ich sehr unsicher wo ich überhaupt anfangen muss mit der Fehlersuche, bzw. wo das Problem liegen könnte.
Wenn einer eine Idee hat wo der Fehler sein kann, poste ich auch gern etwas Code. So macht das aber noch nicht viel Sinn.   

Was ist eigentlich die Exception 5? Und tritt das Problem bei anderen auch auf?
Ich muss auch zugeben, dass ich mit dem Debuggen etwas überfordert bin und nicht so richtig weiß wo ich ansetzten sollte.

Ich freue mich auf eure Antworten
Sava
18
Lowlevel-Coding / Re: kprintf char ausgeben
« am: 12. May 2016, 09:38 »
Ich glaube wir reden an einander vorbei. Ich bin noch nicht so fit mit den Begriffen und werfe da bestimmt was durcheinander. Meine Eingabe ist von der Ausgabe getrennt.
Tatsächlich hat nicht meine Ausgabefunktion ( = kprintf) die Keycodes benutzt sondern mein Konsolentreiber ( macht die tatsächlichen Ausgaben auf dem Bildschirm).
Wobei ich gestehen muss, dass ich jetzt erst mal meinen Code besser strukturiert habe (und da sicher noch Optimierungsbedarf besteht).
Ich denke ich komm erst mal klar. Die Übersetzung von UTF-8 in CP437 steht auch schon, sodass mein Tastaturtreiber komplett mit UTF8 arbeitet und die Übersetzung erst im Konsolentreiber stattfindet.
Wenn ich noch ne Portion Mut finde lade ich das ganze Projekt mal irgendwo hoch und lass mir ein dickes Fell wachsen für die ganze Kritik ;)
danke!
19
Lowlevel-Coding / Re: kprintf char ausgeben
« am: 12. May 2016, 08:26 »
Uff, das war erst mal viel Information.
Aber ich denke ich habe einen ganz guten Überblick wie's weiter geht (und noch viel zu tun ^^)

Zitat
Was meinst du mit Ausgabe? Der Keycode ist doch eine Eingabe und keine Ausgabe?
Der Keycode ist die Eingabe. Ich meinte dass ich den Keycode weiterreiche an meinen Konsolentreiber, der dann die tatsächliche Ausgabe auf den Bildschirm macht.

Danke, den Rest krieg ich hin.
Gruß
Sava
20
Lowlevel-Coding / Re: kprintf char ausgeben
« am: 11. May 2016, 11:30 »
Da du bei deiner Antwort nicht weiter auf die Übersetzung von UTF8 auf CP437 eingegangen bist, gehe ich davon aus, dass ich das so Umsetzen kann?

Zitat
Am sinnvollsten wäre es, für solche Tasten ein Interface bereitzustellen, das Keycodes benutzt
Tatsächliche habe ich sowas schon versucht. Ich habe also für Pos1 den dazu gehörigen Keycode (71) an meine Ausgabe gesendet und dann entsprechend abgefragt. Bei Pos1 hat das auch gut funktioniert. Für die Pfeiltasten (72,75,77,80) hat dies nicht mehr geklappt. Ich kann mir nicht erklären was schief gegangen ist, aber meine Cursorposition wurde seltsam verschoben. Wenn dies aber eine Lösung dafür ist, denke ich mich da noch mal rein.

danke!
Seiten: [1] 2

Einloggen