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 - FlashBurn

Seiten: 1 ... 30 31 [32] 33 34 ... 43
621
Lowlevel-Coding / Re:Shared Memory
« am: 02. October 2010, 20:02 »
Zitat von: erik
Das könnte schon funktionieren aber ich glaube nicht das sowas schon mal jemand ernsthaft gemacht hat.
So blöd es klingt, doch ;)

Es wird dir nämlich empfohlen für bestimmte Exceptions nen TaskGate zu nehmen, weil dann ein neuer Stack geladen wird.

Wird unter OS-X nicht was ähnliches gemacht, wimre habe ich mal was gelesen das dort der Kernel gar nicht in jedem Prozess eingeblendet ist, sondern das nur ein "Stub" existiert der dann das PageDir wechselt, in den Kernel rein.
622
Lowlevel-Coding / Re:Shared Memory
« am: 02. October 2010, 15:56 »
Nope, alles soweit korrekt.

Und genau deswegen (weil man ja eh alles braucht was man auch für Kernel-Threads braucht), sollten doch Kernel-Threads auf x86 nicht so schwer sein.
623
Lowlevel-Coding / Re:Shared Memory
« am: 02. October 2010, 09:38 »
Zitat von: erik
Wie ist das bei CreateThread(), da musst Du doch schon genau wissen wie viele Stacks erstellt werden müssen?
Jap, richtig. Ich habe im Moment noch 2 Funktionen (die auch noch fast genauso aussehen) und will die mal in eine vereinen.

Zitat von: erik
Für einen richtigen Slab-Allocator sehe ich da nirgends eine Verwendungsmöglichkeit oder meinst Du etwas anderes in meinem OS?
Naja, alles wofür du ein kmalloc/kfree einsetzen würdest.

Ich habe kein kmalloc/kfree in meinem Kernel, da wird alles über den SlabAllocator gemacht, weil ich ja nur Objekte bekannter Größer allokieren möchte und das halt mit dem SlabAllocator wesentlich schneller geht.
624
Lowlevel-Coding / Re:Shared Memory
« am: 02. October 2010, 08:55 »
@svenska

Das ist genau das was ich in meinem Kernel mache. Da sind wir uns als mal so richtig einig ;)

Zitat von: erik
Sicher? Für einen User-Mode-Thread musst Du auch einen User-Mode-Stack anlegen und wieder löschen, für einen Kernel-Mode-Thread nicht. Auch muss ein User-Mode-Thread zu einem Prozess gehören im Gegensatz zu einem Kernel-Mode-Thread. Ich denke diese kleinen Fallunterscheidungen werden noch an einigen anderen Stellen erforderlich sein.
Was das wieder freigeben betrifft, da ich eh auf "0" überprüfe bevor ich freigebe, ist es egal ob ein Stack vorhanden ist oder nicht.
Auch ein KernelThread kann bei mir zu einem Prozess gehören (wird sogar bei jeder Prozesserstellung genutzt).
Zumal auch der Kernel ein Prozess ist (um viele Sachen einfacher zu machen hat bei mir der Kernel auch die selben Prozessstruturen wie alle anderen auch und ist der Prozess mit der ID 1 oder 0 da bin ich mir grad nicht sicher).

@erik

Da du ja nen MikroKernel haben willst und deine Msgs über Segmente erstellt werden, solltest du eventuell überlegen nur nen SlabAllocator zu benutzen. Denn im Endeffekt allokierst du ja nur Objekte bekannter Größe und da ist der dann schneller (und an sich auch Speicher schonender).
625
Lowlevel-Coding / Re:Shared Memory
« am: 01. October 2010, 19:11 »
Zitat von: erik
Das bedeutet aber das mindestens CreateThread() und KillThread() doppelt oder zumindest mit verschiedenen Ausführungspfaden da sein müssen.
Nope, nur CreateThread() (und selbst das könnte ich verhindern, denn der Unterschied ist wirklich minimal bzw. werde ich das bald über ein Flag machen => läuft auf eine if-Schleife hinaus mit einmal 5 Zeilen und einmal 3 Zeilen Code) und KillThread interessiert es wieder gar nicht was für ein Thread das ist, da man eh auf ungültige Werte prüfen sollte.

Zitat von: erik
Dafür könnte ich ja meinen DoIdle-Syscall benutzen. Aber ich glaube nicht dass das nötig ist, ich sehe einfach kein Problem darin das ein Thread seine eigenen Ressourcen wegräumt.
Da brauchst du dann aber ein wirklich gutes kfree(). Denn wenn auf allen CPUs zur gleichen Zeit Threads beendet werden und diese ihre Ressourcen (je nach dem wie viele das sind, könnte das auch mal dauern) freigeben, müsstest du ja irgendwo einen Lock (mind.) haben und da sind wir dann wieder da was man als lange empfindet. Denn in der Zeit kann ja nichts anderes gemacht werden, da ja dein Kernel nicht unterbrechbar ist.
626
Lowlevel-Coding / Re:Shared Memory
« am: 01. October 2010, 17:42 »
Zitat von: erik
Mit einem kfree(), ich verstehe nicht worauf Deine Frage abziehlt.
Naja, ich finde/fand es immer nicht wirklich einfach diese ganzen Ressourcen von dem Thread freigeben zu lassen der ja noch läuft (wie gibt man denn Stack und PageTables/Dir frei wenn der Thread noch läuft) und das wäre halt ein guter Grund für mind. einen Kernel-Thread.

Zitat von: erik
Ich meine die 3 Worte zwischen den Klammern. Der idle-Prozess wird bei mir ja nicht zur Laufzeit per CreateProcess() gebaut (hab ich auch in dieser Diskussion erklärt) sondern ist schon da wenn der Kernel zum Leben erwacht.
Ändert ja nichts daran, das du dafür ne Extra-Behandlung, wo auch immer, benötigst und du ja geschrieben hast, dass das nicht so toll ist zwecks Fehler.
Der Punkt ist einfach, der Idle-Thread ist halt was "besonderes" und wo ich den nun mit extra Code besonders behandle ist doch egal (ob Scheduler oder Boot-Code).
627
Lowlevel-Coding / Re:Shared Memory
« am: 01. October 2010, 15:40 »
Zitat von: erik
Ich sehe eben 2 verschiedene Arten von Threads und um diese auf die CPU zu bringen benötigst Du 2 verschiedene Mechanismen (auch wenn die Unterschiede nur marginal sind).
Jetzt sind wir zwar wirklich beim Haare spalten, aber egal.

Der für mich einzige wirkliche Unterschied zw. Kernel- und User-Threads liegt in der Erstellung, wenn man den Stack aufbauen muss, ansonsten ist es auch meinem Scheduler egal (und er weis es nicht mal direkt) was das für ein Thread ist.

Zitat von: erik
Bis jetzt hab ich noch kein Killer-Argument für Kernel-Mode-Threads bei Micro-Kerneln gesehen.
Wie willst du Threads/Prozesse beenden und ihre Ressourcen freigeben?

Zitat von: erik
Deswegen muss das ja auch freigeschaltet werden damit nur die Threads des idle-Prozess das dürfen.
Darauf möchte ich jetzt mit etwas antworten, was du geschrieben hast:
Zitat von: erik
... als an mehreren Stellen im Kernel-Code extra Spezialfallbehandlungen zu implementieren.
628
Lowlevel-Coding / Re:Shared Memory
« am: 01. October 2010, 15:17 »
Zitat von: erik
Alle üblichen Wechsel in den Ring-0 (INT-Befehle, IRQs und Exceptions) deaktivieren auf x86 immer das IE-Flag womit zumindest suggeriert wird das der Ring-0 nicht per Default unterbrechbar ist. Es ist aus meiner persönlichen Sicht ein kleines x86-Design-Mysterium das der HLT-Befehl zwar in einem unterbrechbaren Umfeld sein muss (sonst käme die CPU da ja nicht mehr raus) aber nur in einem Umfeld benutzt werden kann das per Default nicht unterbrechbar ist.
Das ist, wie dir taljeth ja schon gesagt hat, nicht korrekt.

Was mir noch aufgefallen ist, es dürfte verdammt schwierig werden andere OS auf deine Platform zu portieren, wenn dein System-Mode Grundsätzlich nicht unterbrechbar ist.

Ansonsten seh ich immernoch kein Problem damit das "hlt" nur im Ring0 ausgeführt werden kann, genauso wenig damit, das meine Idle-Threads auch Kernel-Threads und keine kompletten Prozesse sind.
629
Lowlevel-Coding / Re:Shared Memory
« am: 29. September 2010, 18:40 »
Zitat von: erik
Das macht aber den Scheduler komplizierter als nötig, der muss dan ja normale User-Mode-Threads, User-Mode-Threads die nicht auf der Runnable-Liste stehen und Kernel-Threads (eventuell auch mit und ohne Runnable-Liste) unterstützen. Das wäre mir zu aufwendig, mein Scheduler soll genau eine Art von Threads kennen und die auch immer auf die selbe Art an die CPU lassen. Bei mir dient der idle-Prozess auch dazu das der Scheduler niemals auf eine komplett leere Runnable-Liste stößt (wie ich mehrere Teillisten für die unterschiedlichen Prioritäten verwalte weiß ich noch nicht genau).
So kompliziert ist das gar nicht. Ich habe eine Datenstruktur wo Sachen drin stehen die pro CPU gelten und da ist auch ein Pointer zum entsprechenden Idle-Thread drin.
Ich rufe ne Funktion auf, die mir den Thread mit der höchsten Priorität aus der Ready-Queue holt, gibt die Funktion 0 zurück, wird der Idle-Thread ausgeführt.

Warum einen extra Prozess für das Idlen erstellen?

Zitat von: erik
Aha, dann würde ich den HLT-Befehl als Syscall anbieten den nur der idle-Prozess benutzen darf.
Da hätte ich dann aber ein Problem, wenn ich deine Ideen umsetzen würde. Denn mit deaktivierten Ints (zwecks nicht unterbrechbar) macht der "hlt" nicht viel Sinn.
630
Lowlevel-Coding / Re:Shared Memory
« am: 29. September 2010, 14:44 »
Zitat von: erik
Definiere mal Bitte "die CPU nichts zu tun hat". Das einzigste Kriterium ist doch das wenn es gar keine "runnable" Threads gibt und da es noch die Threads vom idle-Prozess gibt (die eigentlich niemals blockieren) wird diese Bedingung nie erfüllt.
Mein Idle-Threads tauchen nicht in der Liste auf, von daher kann das funktionieren.

Zitat von: erik
Wie kommt es zur zweiten Situation? Warum wird nicht auch in der ersten Situation Energie gespart?
Die zweite Situation hab ich dir ja oben erklärt. Naja, ich dachte mir halt das es auch Threads geben muss die nur Laufen wenn wirklich kein anderer die CPU braucht und dann muss ja auch nicht unbedingt Energie gespart werden.

Zitat von: erik
Da bin ich mir jetzt auch nicht sicher, was sagt den das Intel-Manual dazu?
Sagt Ring0.
631
Lowlevel-Coding / Re:Shared Memory
« am: 28. September 2010, 09:46 »
Zitat von: erik
Mit jeder Kernel meinte ich jeden Kernel der auf eine neue HW-Plattform (wobei jetzt mal PC mit nur PIC und PC mit HPET schon zwei verschiedene Plattformen sind) kommt bekommt zu seinem Unterbau (also die fest eingebauten Treibern) ein angepasstes API was es ihm ermöglicht die spezielle HW auch so gut als möglich auszureizen. Das API zu den Applikationen (die Syscalls) bleibt natürlich immer gleich. Ich hoffe jetzt hab ich genau das getroffen was Du meinst.
Das ist so ungefähr das was ich geplant hatte.

Zitat von: erik
Jetzt bin ich aber neugierig, worin unterscheiden sich diese beiden Dinge? Wie entscheidet der Kernel oder jemand anderes darüber welche dieser Möglichkeiten gewählt wird? Gibt es von beiden Sorten so viele Threads wie es CPUs gibt? Warum muss der HLT im Kernel ausgeführt werden?
Sie unterscheiden sich dahingehend, das so Programme immer nur dann ausgeführt werden wenn die CPU nichts zu tun hat, dann wird aber kein Strom gespart. Die Wahl ist ganz einfach, Idle-Threads (ohne "hlt") sind bei mir Priorität 0 und laufen, wie gesagt, nur wenn keine anderen Threads laufen und wenn gar keine Threads in der ready-Queue sind, läuft der richtige Idle-Thread der dann ein "hlt" ausführt.
Ich bin der Meinung das "hlt" nur im Ring0 ausgeführt werden darf, deswegen sind das Kernel-Threads.

Zitat von: erik
Also eine Art Garbage-Collector, interessant das Du so eine Idee umsetzen willst.
Nicht wirklich, denn nen Garbage-Collector rufst du ja nicht auf und dieser Thread ist aus der Not geboren, weil ich keine bessere Idee hatte.
So ist es halt einfacher, sowas wie Stack, Thread-Discriptor und solche Sachen freizugeben.
Der Thread wird per Semaphore aufgeweckt.

Zitat von: erik
Ja ich meine wirklich genau das was ich geschrieben hab. Welche Daten-Strukturen sollte meine CPU denn dafür kennen? Ich bin mir nicht bewusst irgendwelche Dinge vom Speicher genannt zu haben, meine CPU soll, mit Ausnahme der Descriptoren für Segmente und Pages, überhaupt nicht selbstständig auf den Speicher zugreifen. Der Zeitscheiben-Counter ist eh in HW implementiert (ein simpler Downcounter in den der Scheduler immer die Länge der Zeitscheibe des nächsten Thread reinlegt und der bei 0 aufhört zu zählen und eine Yield-Exception generiert also einen Kontext-Switch auslöst durch den dann der Scheduler aktiv wird) und kann daher auch dort manipuliert werden und Exceptions muss die CPU auch so auslösen können. Ein kleiner zusätzlicher Downcounter der die Befehle zählt und bei != 0 die IRQ-Annahme + Zeitscheiben-Counting sperrt ist IMHO keine so große Erweiterung mehr.
Also sowas wie nen APIC, denn was du beschreibst ist kein extra Timer-Chip, der muss in der CPU sitzen.

Zitat von: erik
Weder ARM noch MIPS oder PowerPC sind nur Mikrocontroller! Die beiden letzten sind sogar in 64 Bit verfügbar und wurden schon in sehr großen Super-Computern eingesetzt! Was ist eigentlich an Mikrocontrollern so schlimm?
Naja nen Mikrokontroller der genug Leistung und die Möglichkeit zur Eingabe und zur Bildschirmausgabe hat, ist einfach zu teuer. Ich weiß das es da genügend von gibt, aber das finanzielle spielt da halt auch ne Rolle und nur im Emulator testen wollte ich dann auch nicht. Das ist ein weiterer Grund ich habe schon Schwierigkeiten nen vernünftigen Emulator für ARM zu finden, der unter Windows läuft und nicht alzu schwer zu bedienen ist (da wäre nur Qemu aber selbst kompiliert bekomme ich es nicht und richtig zum Laufen hab ich den ARM Emulator auch noch nicht bekommen).
632
Lowlevel-Coding / Re:Shared Memory
« am: 27. September 2010, 18:13 »
Zitat von: erik
Du meinst das jeder Kernel ein Interface bekommt das individuell auf die entsprechende HW angepasst ist?
Selbstverständlich nicht, jeder Kernel muss die selben Syscalls zur Verfügung stellen (da frag ich mich gerade was meinst du eigentlich genau mit "jeder Kernel"?), aber ich wäre halt froh wenn man nur einmal abstrahieren müsste. Da ich aber verschiedene Module habe, müssen diese alles das selbe Interface implementieren damit keine "Symbol nicht gefunden" Fehler passieren können.

Zitat von: erik
Bei mir ist idle ein User-Mode-Prozess. Da idle bei mir das Speicherdefragmentieren übernehmen soll hatte ich auch mal überlegt dafür doch Kernel-Mode-Threads zu implementieren aber ich denke es wird auch ohne gehen, der Kernel stellt ein paar spezielle Syscalls zur Verfügung die nur idle benutzen darf.
Naja, ich unterscheide zw dem Idle-Thread (der wirklick nur "hlt" ausführt und im Kernel laufen muss) und anderen Idle-Threads, die immer dann laufen wenn nichts ansteht.

Zitat von: erik
Der klingt aber gefährlich, welche Art von Programmen muss sich den vor dem in Acht nehmen?
Jeder ;) Das ist mein Thread der Prozesse/Threads vollständig beendet (also deren ganze Ressourcen freigibt und sowas).

Zitat von: erik
Wenn dieser IRQ-Disable-Befehl kommt rechnet die CPU die Strafzeit, z.B. pro Befehl 4 us, aus und verringert die Restzeitscheibe entsprechend, falls die übrige Restzeit <=0 ist gibt es sofort eine Yield-Exception und der IP wird auf diesen IRQ-Disable-Befehl gesetzt (so das wenn dann dieser Thread wieder vom Scheduler dran kommt ein neuer Versuch unternommen wird).
Sicher das du das meinst was du geschrieben hast? Weil das hört sich danach an, das deine CPU deine Datenstrukturen kennt.

Ansonsten ist sowas natürlich zu begrüßen.

Zitat von: erik
Dann sollte der Compiler sich darum kümmern und die Funktion inlinen.
Das geht nicht, da diese Symbole ja erst beim Booten aufgelöst werden.

Zitat von: erik
ARM ist auch recht gut Dokumentiert (vor allem zu diesen voll integrierten SoC-Chips gibt es oft downloadbare Manuals mit über 1000 Seiten) und hinter dem genannten Board steht eine Community die sicher auch noch die restlichen Fragen beantworten kann.
Gut dann das Argument das ich ein Consumer-OS schreibe und nicht eins für nen Mikrokontroller. Das BeagleBoard kommt dem schon am nächsten, aber ich hab halt nicht einfach mal so 150€ rumliegen :(

Ich sags mal so, wenn ich einen rein finanziellen Grund hätte, würde ich mir irgendein Nischen-Produkt suchen und dafür ein OS schreiben, da das bestimmt mehr Erfolg hätte, aber so nehme ich die Arch die am weitverbreitesten ist (unter normalen PCs) ergo x86. Ob die Arch toll ist seih mal dahingestellt.
633
Lowlevel-Coding / Re:Shared Memory
« am: 27. September 2010, 15:35 »
Zitat von: erik
Die einzigste HW die mir da einfällt ist eben der Timer aber auch der wird bei einem Micro-Kernel nur dazu benutzt irgendwelchen User-Mode-Prozessen eine Message zu schicken bzw. Threads aufzuwecken, sollte also auch ziemlich schnell sein.
Mir geht es gar nicht darum das es eventuell "länger" dauern könnte, sondern das ich gerne ein einheitliches Interface hätte (das perfekte Interface kann meiner Meinung nach nicht existieren bzw. wäre es mir zu langsam ;) ) was das betrifft.

Zitat von: erik
Bist Du sicher? Bitte nicht falsch verstehen aber bist Du wirklich sicher das in Deinem Code keine potentiellen Dead-Locks usw. drin sind oder sind die bis her nur nicht aufgetreten?
Sicher kann man nur so lange sein, bis einer auftritt ;) Ich hatte erst einen (daher auch der Thread, der war nämlich die Ursache) und der war ziemlich dämlich :(
Ich habe bei einem Read-Write-Lock, als Reader den Lock bekommen und habe ihn als Writer wieder freigegeben (bzw. hat der Code das versucht und hat mein OS festgefahren).

Zitat von: erik
... oder für die der Kernel eigene Threads braucht.
Ich habe z.B. pro CPU 1 Idle-Thread und das ist ein Kernel-Thread und dann kommt noch mein "Thread-Killer" dazu.

Zitat von: erik
Wo siehst Du das Problem?
Wie stellst du sicher dass das Programm die Ints nicht für immer deaktiviert? Das ist der Grund warum man sowas für gewöhnlich nicht zulässt.

Zitat von: erik
Ein sauber programmierter und klar strukturierter Kernel in dem der Programmierer sich gut zurecht findet (der deswegen vielleicht weniger Fehler enthält) ist IMHO sehr viel mehr wert!
Sorry, aber das klingt für mich nach Uni-gelabber ;) Du müsstest es doch besser wissen, das es in der Arbeitswelt sowas nicht gibt, da soll immer alles schneller als möglich gehen und das ist für mich auch ein Grund warum wir zwar immer schneller CPUs haben, aber irgendwie werden viele (bzw. bei nem normalen User fast alle) Programme nicht schneller.

Zitat von: erik
Ich weiß ja nicht wie Du Interfaces entwickelst aber solche Funktionen hatte ich noch nie (und wenn doch würde die ein guter Compiler wegoptimieren).
In dem Fall ging es darum, das die HW nicht dieses Feature unterstützt hat.

Zitat von: erik
Die armen Kernel-Threads, das empfinde ich schon als erhebliche Einschränkung.
Korregiere mich wenn ich falsch liege, aber ersten wozu brauchst du ne FPU im Kernel und welcher Kernel unterstützt das (wimre ist das auch bei Linux ne Regel, das ist aber nur ne wage Erinnerung ;) )?

Zitat von: erik
Wenn Du so denkst, warum programmierst Du dann Dein OS ausgerechnet für x86?
Fast alles bekannt und einfach zugänglich, es gibt genügend Bsp., ich kann es wunderbar einfach testen und ich komme billiger als billig an Hardware.
Wenn ich nicht so knapp bei Kasse wäre, hätte ich schon längst nen BeagleBoard!

Zitat von: erik
Ich schreibe zwar definitiv kein portables OS aber wenn ich es tun würde würde ich mich schon bemühen meine Zeit etwas effizienter zu verwalten. Nimm es mir nicht über aber gleich den ganzen Kernel (und sei es nur ein Micro-Kernel) neu zu programmieren halte ich für reichlich ungeschickt, das geht mit einer guten Modularisierung auf Quell-Code-Ebene deutlich besser.
Ich behaupte das es nicht wirklich lange dauern sollte, meinen Kernel auf ne andere Architektur zu portieren (das weis ich aber auch erst, wenn es denn mal passiert ist).
634
Lowlevel-Coding / Re:Shared Memory
« am: 27. September 2010, 12:58 »
Zitat von: erik
... das eigentliche OS läuft also bereits bevor auch nur das erste PCI-Gerät gefunden ist.
Naja, das ist jetzt Definitionssache, was du als OS bezeichnest, was du vielleicht meinst ist der Kernel und das da weniger Aufwand als bei einem monolithen ist, dürfte klar sein (macht ja auch weniger).
Ich meine aber wenn du einen monolithen mit einem mikro vergleichst, dann kann man sagen dass das OS erst läuft wenn alle Server und Treiber laufen und bis dahin ist es dann doch um einiges komplexer bei einem Mikrokernel.

Zitat von: erik
Also erst mal muss man nicht immer gleich die IRQs abschalten, schon weil der IRQ-Handler in einem Micro-Kernel ja nichts weiter macht als eine Message an einen (unterbrechbaren) User-Mode-Treiber zu schicken.
Sollte er  :roll:

Ich muss mir bei mir nochwas schönes einfallen lassen, da ich auch Hardware habe (Timer) die ihr Arbeit nicht im UserMode sondern im KernelMode verrichten, aber eigentlich wollte ich das die richtigen Treiber dann wirklich nur ne Nachricht bekommen bzw. aufgeweckt werden.

Zitat von: erik
Aber ich will Dich nicht von Deinen Plänen abhalten, implementiere ruhig einen unterbrechbaren Kernel und erzähle uns hinterher wie einfach das war.
Also es war wirklich nicht schwierig ;) (mein Kernel war von Anfang an so geplant und das war mit das erste was ich implementiert habe).

Zitat von: erik
Wenn man den Kernel unterbrechbar macht dann muss man anfangen Dinge wie kmalloc dagegen abzusichern und das kann in ziemlich viel Arbeit ausarten.
Kann sein das ich da anders ticke, aber die Arbeit etwas Multithreading tauglich zu machen ist im Kernel- und UserMode eigentlich gleich. Denn du musst halt einfach die Datenstrukturen wo ein gleichzeitiger Zugriff nicht möglich ist durch irgendetwas schützen und das geht halt wesentlich effizienter wenn man dann die Ints abschalten kann (aber das hatten wir schonmal diskutiert).

Zitat von: erik
Wenn es Dir um das Abschalten der IRQs im User-Mode geht
Nein! Man sollte nichtmal daran denken, das ein UserMode Programm die Möglichkeit hat die Ints abzuschalten, das wäre genauso "dämlich" wie cooperatives-Multitasking. Sicher kann das auch funktionieren, aber einem warum sollte man es einem Programm so leicht machen den PC unbenutzbar zu machen!?

Zitat von: erik
Timer messen die Zeit und sind oft in der Lage zu bestimmten Zeitpunkten einen IRQ zu generieren. Wenn man das hinter einen vernünftigen/flexiblen Interface verbirgt dann gibt es da kein Problem.
Da mein Kernel schon einige Interfaces hat (weil er aus Modulen besteht die vom Loader zusammengefügt werden), weis ich das ein Interface zwar für einen Programmieren schön ist, aber wenn ich daran denke, wie viele sinnlose Funktionen (z.B. "uint32t foo(void bar) { return 0; }") ich dadurch habe. Dann kann ich gerne darauf verzichten.

Zitat von: erik
Wie willst du das eigentlich für Kernel-Threads realisieren oder dürfen die keine FPU benutzen?
Also erstens wenn man Kernel-Threads hat, dann kannst du die genauso benutzen wie User-Threads (es funktioniert bei mir also, theoretisch) und zweitens ist eine Regel von mir keine FPU im Kernel ;)

Zitat von: erik
Nur zu, klar gibt es sehr viele Unterschiede aber das sind überwiegend Details. Die Grundkonzepte sind überall gleich, schon weil alle CPU-Hersteller (außer ich) wollen das die üblichen Betriebssysteme (Linux usw.) problemlos darauf laufen.
Und genau damit habe ich ein Problem. Wenn man immer darauf bedacht ist kompatibel zu bleiben wird nichts richtiges neues mehr Entwickelt.
Wo wir wieder bei dem Henne-Ei-Problem wären. Wir halten an den ganzen alten Sachen fest und das hindert uns daran was richtig neues zu machen.

Zitat von: erik
Ja ist es nicht einfach nur eine Frage des Betrachtungsstandpunktes? Ob man nun von den Unterschieden ausgeht und die jeweils neu implementiert und dann das Gemeinsame hinzu fügt oder ob man vom Gemeinsamen ausgeht und jeweils die Unterschiede individuell hinzufügt kommt doch im Endeffekt auf das selbe Ergebnis hinaus. Die Frage ist wo Du die Grenze ziehst. Also in welchem prozentualem Verhältnis sollen der gemeinsame Code und der individuelle Code zueinander stehen?
Richtig! Und ich schreibe lieber meinen Kernel neu ;)
635
Lowlevel-Coding / Re:Shared Memory
« am: 26. September 2010, 21:09 »
Zitat von: erik
Also da sehe ich kaum Probleme (kommt aber sicher noch wenn ich meine Ideen in die Realität überführen muss), es erfordert nur einiges an fertiger Infrastruktur bis ein printf("Hello Wordl\n"); korrekt über IPC funktioniert als nur mit nem simplen Syscall.
Mir ging es noch nicht mal um so ein Bsp., sondern darum dein OS erstmal lauffähig zu bekommen. Ich meine bei einem monolithen wo auch noch alle Treiber in den Kernel reinkompiliert sind, brauchst du nur den Kernel laden und alles läuft (vereinfacht). Bei nem Mikrokernel, müssen Treiber und Server samt Kernel geladen werden und dann gibt es auch noch Abhängigkeiten bzw. Sonderfälle, weil wie "läd" man eine Datei ohne das der nötige Server dafür geladen wurde (bzw. wie lädst du die Library die der VFS-Service benötigt)?
Sowas in der Richtig, nicht solch einfache Sache wie IPC ;)

Zitat von: erik
Wieso muss der Kernel deswegen unterbrechbar sein?
Wieso denn nicht? Ich weiß noch immer nicht, was daran so schlimm sein soll (oder schwierig).

Zitat von: erik
Abgesehen davon das die Synchronisation unabhängig von CPU-Modus immer die selben Konzepte benutzt haben Synchronisation im Kernel und im User-Mode nichts miteinander zu tun.
Mir ging es darum, das sich eine Semaphore (als Bsp.) effektiver/effizienter im KernelMode implementieren lässt, da man dort auch die Ints ausschalten kann (ist einfach effizienter als den Scheduler aufzurufen bzw. von diesem unterbrochen zu werden).

Zitat von: erik
Da gibt es nichts was der Compiler nicht wegabstrahieren könnte. Alle CPUs führen im wesentlichen Rechenbefehle aus und greifen auf eindimensionalen Speicher zu. Wink
Das einzigste was in einem Kernel für jede CPU individuell sein muss sind die paar unvermeidlichen Assembler-Stückchen und ein paar Strukturen (für allerlei Descriptoren und die gesicherten Register).
Da wären in meinem Fall die Timer, die FPU Behandlung (besonders das lazy Laden/Speichern des FPU Contextes wie ich es auf x86 mache, dürfte es so nicht auf ARM geben), IRQ-Management, Paging und mir fallen bestimmt noch mehr Sachen ein, wenn ich mich mal mit ARM beschäftigen würde.

Ich finde es auch einfach sauberer und übersichtlicher einen neuen Kernel zu schreiben als alles wegzuabstrahieren (der Code der trotzdem in allen Kernel verwendet wird ist natürlich ne andere Sache/Problem).
636
Lowlevel-Coding / Re:Shared Memory
« am: 26. September 2010, 11:52 »
Zitat von: erik
Was macht Dich da so sicher?
Weil ich noch keinerlei Erfahrung mit A-I/O habe  :wink:

Zitat von: erik
Du programmierst an einen monolithischen Kernel?
Um Gottes Willen, nein!!!!

Zitat von: erik
Klar ist schon deswegen ein Micro-Kernel leichter zu programmieren weil er eben nicht unterbrechbar sein muss. Wenn in dem Kernel keine der normalen Dienste (wie VFS, TCP/UDP/IP, Treiber, Geräte-Management usw.) drin sind dann entsteht auch keinerlei Nachteil wenn er nicht unterbrechbar ist.
Naja, der Kernel an sich ist leichter zu programmieren, aber der Rest des OS ist in vielen Sachen schwieriger (Huhn-Ei-Problem).
Wenn man, wie ich, die Speicherverwaltung im Kernel macht, dann sollte der Kernel schon unterbrechbar sein, zumal wo ist denn bitte das Problem damit? Wenn du nachher im UserMode dich eh mit Synchronisation befassen musst, kannst du das doch auch schon im Kernel machen, zumal ich finde das es dort einfacher ist.
Wenn ich jetzt mal von einem 4 CPU System ausgehe und der Prozess 4 Threads hat die alle zur gleichen Zeit laufen und alle dummerweise auch noch zur gleichen Zeit nen Syscall machen, dass sie mehr Speicher brauchen. Dann möchte ich (wie du das siehst weis ich ja ;) ) das mein Kernel unterbrechbar ist, weil ich nicht alle 4 Threads gleichzeitig in meinen Datenstrukturen rumspielen lassen und wenn dann der Kernel nicht unterbreachbar ist, dann kann das schon mal ne "Weile" dauern bis auch der letzte Thread seinen Speicher hat.

Zitat von: erik
Was? Wegen solcher Kleinigkeiten (und das sichern der Register ist wirklich nur ein winziges Detail) willst Du gleich einen neuen Kernel programmieren?
Das mit dem Monolithen habe ich mal weggelassen ;)

Es gibt bestimmt noch andere Unterschiede zw ARM und x86! Mir geht es darum, das man nicht immer alles versuchen sollte gleich zu machen, sondern jede Architektur sollte bestmöglichst ausgenutzt werden und gerade bei einem Mikrokernel sollte der Aufwand nicht so groß sein.
Ich meine mein PMM und VMM kann ich ja beibehalten, aber den Rest würde ich sehr großzügig neu schreiben wollen.

Zitat von: erik
Bei Kernel-Threads stellt sich eben das Problem in welchen Speicher-Kontext sie sind, eigentlich müssten sie ja in allen Kontexten drin sein, so wie der ganze Kernel ja auch. Außerdem müssen diese Threads auch vom Scheduler berücksichtigt werden und der muss beim reinspringen in so einen Kernel-Thread ja keinen Kontext-Switch machen sondern nur den Stack umschalten.
Naja, wenn ich einen reinen Kernel-Thread habe (der also auch nie in den UserMode geht) dann tausche ich bei mir auch nur den Stack aus. Ist es aber ein Thread der sich nur gerade im KernelMode befindet tausche ich auch noch CR3 aus.
Ich sehe da wie gesagt nicht so das Problem oder die Schwierigkeit.

Zitat von: erik
Da würde ich mal QNX empfehlen, die rühmen sich u.a. damit das der Kernel niemals ein Eigenleben entwickelt sondern nur per Kommando (da gibt es nur Syscalls, Exceptions und HW-Interrupts) aktiv wird und so schnell wie möglich wieder fertig ist. Klar gibt es unter den Syscals einige die länger dauern, z.B. sowas wie AllocPages oder CreateProcess, aber es ist bei QNX recht gut dokumentiert welche Syscalls in deterministischer Zeit fertig sind und welche nicht. Außerdem soll er POSIX-konform sein.
Der Source von QNX war ja mal verfügbar, aber ist er das immernoch wimre war da doch was, dass der nur noch für zahlende Kunden zu sehen ist?

Zitat von: erik
Wozu? Der PopUp-Thread kann doch gleich die passende Arbeit selber erledigen, da besteht doch kein Grund zur Eile, schließlich dürfen pro Message-Target auch mehrere PopUp-Threads aktiv sein.
Mit irgendwo hinschreiben meinte ich halt das was ich dann mit der Bitmap geschrieben habe, denn du kannst ja schlecht nen neuen Framen rendern, jedes Mal wenn ein Popup-Thread ne Nachricht bearbeitet, das wäre 1. bestimmt nicht einfach und 2. könnte es dann wohl ne ganze Weile dauern bis mal wieder ein neuer Frame berechnet wird, wenn der Nutzer nichts macht.

Zitat von: erik
Die klingt so wie meine Idee! Wenn das weiter so geht muss ich noch Lizenz-Gebühren verlangen.
Zum Glück ist es doch nicht das gleiche ;)

Was mir aber dann bei meinem Konzept wieder auffällt. Es ist egal ob der Client den Speicher bei der Anfrage mitsendet oder ob er ihn mit der Antwort erhält.
Im Code sollte das nicht viel anders aussehen. Man muss nicht mal großartig umdenken, deswegen frage ich mich halt wo das große Problem damit ist (das finde ich vielleicht dann wenn ich dann irgendwann mal Programme portiere oder schon bei meiner libc).
637
Bei mir hast du die Möglichkeit einem Port einen Namen zu geben und jeden Namen darf es nur einmal geben (ist case-sensitive) oder du übergibst nen leeren String.
Ansonsten hatte ich überlegt die wichtigsten Server über eine Liste im Kernel zu verwalten (wo deren Portnummern drin stehen) und diese Liste kann man sich dann als UserApp holen.

Denn ansich müssen ja nur die Portnummern der Server/Services bekannt sein. Die Treiber (und ähnliche Sachen) registrieren sich dann, genauso wie ein Client, beim Server und nur dieser braucht ja die Portnummern bzw. kann sie gegebenenfalls ja weiterreichen.
638
Lowlevel-Coding / Re:Shared Memory
« am: 25. September 2010, 19:54 »
Zitat von: svenska
Minix stammt aus einer Zeit, als man ein billiges Unix für 8086/80286er brauchte. Zero-Copy war da noch kein Thema.
Ich habe mir Minix3 angesehen.

Zitat von: svenska
Du vergisst die Messages vom VFS-Treiber zum HDD-Treiber ("lies mal block xy") und umgekehrt ("bin fertig"). Wobei ich nicht weiß, ob/wie ich da Shared Memory einsetzen würde. Aber ich hab da auch keinen anderen (guten) Ansatz.
Das habe ich weggelassen, weil die sich nicht vermeiden lassen, die anderen Syscalls ist im Endeffekt das einzige wo du etwas verbessern kannst indem du sie einsparst, aber die Nachricht an sich kannst du ja schlecht einsparen ;)

Ich habe mir das so vorgestellt, das du Pages allokiert hast wo die Daten aus Block xy reinsollen und eine Anfrage an den HDD-Treiber sendest das er Block xy in diese Pages schreiben soll. Die Pages werden als SharedMem mit der Nachricht/Anfrage an den HDD-Treiber übergeben.
Dieser läd Block xy in die Pages und sendet eine Antwort zurück das alles i.O. war.

Ich wollte den Syscall so gestallten, das du über ein Flag entscheiden kannst, ob der SharedMem versendet werden soll (er bleibt auch bei dir), ob er geunmappt werden soll (weil du alles gemacht hast und ihn nicht mehr benötigst) oder ob du ihn ganz versenden willst (er wird bei dir geunmappt).

Damit sollte ich dann alle Fälle abgedeckt haben und ich spare mir Syscalls. Im Endeffekt könnte man sogar sagen, dass ich damit ne Art dynamic-size Msgs habe ;) Nur halt auf ein vielfaches der Pagegröße beschränkt.
639
Lowlevel-Coding / Re:Shared Memory
« am: 25. September 2010, 17:59 »
Was ich nach einer kurzen Lesetour durch die Dokumentation sagen kann, ist das Minix lieber einmal zu viel kopiert als einmal zu wenig.
Und das der VFS-Service einen SharedMemory-Bereich an den HDD-Treiber schickt wo er die Daten reinschreiben soll oder drauß lesen soll ;)

Dann werde ich das wohl doch so machen müssen. Damit würde dann ja auch der Sinn eines "Speicher verschicken"-Syscalls wegfallen (ein Glück das ich momentan eh nicht Programmieren kann ;) ).

Edit::

Den Vorteil meiner Methode sehe ich darin, das weniger Syscalls nötig wären:

Bei mir: Speicher allokieren, Speicher versenden
Ansonsten: Speicher allokieren, SharedMem-Bereich erstellen, SharedMem Erlaubnis an anderen Prozess geben, SharedMem beim Empfänger mappen, SharedMem beim Emfpänger unmappen

Das wäre sogar eine ganz schöne Ersparnis!

Edit::

Eigentlich erstellt man doch einen SharedMem-Bereich eh nur dazu, das man den Speicher mit anderen Prozessen "teilen" kann, oder?
Dann wäre es aus performace Sicht nämlich besser nen Syscall zu machen, wo man eine Nachricht verschickt, ein SharedMem Bereich erstellt wird und die ID in die Msg (nicht sichtbarer Teil) gespeichert wird und beim Empfangen wird der SharedMem gleich gemappt und die Adresse wird mit der Msg übergeben.

Wie klingt diese Idee?
640
Lowlevel-Coding / Re:Shared Memory
« am: 25. September 2010, 16:44 »
Zitat von: erik
Ich sage es nur ungern aber falls Du dann später feststellen solltest das Dein Konzept für asynchrones I/O überhaupt nichts taugt wirst Du Dich ziemlich ärgern weil Du dann vor der Entscheidung stehst entweder ein zweites paralleles IPC-System zu implementieren oder alle Programme auf ein neues IPC-System umzustellen oder Dich mit dem Ärgernis irgendwie zu arrangieren oder es einfach ganz bleiben zu lassen. Ich hab es schon mal geschrieben und mache das gerne wieder: solche Arten von Entscheidungen sind ziemlich eklig.
Das sehe ich noch nicht so. Denn ich könnte auch sagen, jede Nachricht wird von einem Thread abgeholt und dann wird ein neuer Thread erstellt der sie bearbeitet (worker Thread). Das ist dann deinen Popup-Threads sehr ähnlich nur das es keinen Pool gibt, den man aber auch schaffen könnte.
Also das Umstellen auf A-I/O sollte nicht das Problem darstellen.

Zitat von: erik
Von einem unterbrechbaren Kernel bin ich allerdings nicht ausgegangen, wenn Du sowas willst hast Du sicher noch ganz andere Probleme als nur die Zuordnung von Stacks. Wer hat den hier einen unterbrechbaren Kernel?
Welche anderen Probleme? Ich habe einen unterbrechbaren Kernel und jeder der nen Monolithischen Kernel schreibt, sollte bitte auch einen haben. Sicher ist das bei einem Mikrokernel nicht mehr so schlimm, aber da wären wir wieder bei dem Thema wie Mikro ein Kernel ist.

Zitat von: erik
Das mag auf x86 ja zutreffen aber auf viele andere CPUs trifft das nicht zu, z.B. ARM. Diese CPUs haben einen gewissen Teil der Register doppelt, einmal für den User-Mode und einmal für den System-Mode, und schalten beim Mode-Wechsel einfach um. Im System-Mode stehen einem gleich ein paar Register zur Verfügung die auch bereits sinnvolle Werte für den Kernel enthalten (z.B. einen Pointer zum Thread-Descriptor des gerade laufenden Threads) und das sichern der paar User-Mode-Register ist damit nicht viel mehr als ein einfacher Speicher-Zugriff.
Das ist z.B. ein Grund warum ich sage, das mein Kernel nicht portabel sein muss, sondern das ich dann für jede neue Architektur lieber einen neuen schreibe. Nur die meisten werden sich für den Anfang einfach auf x86 beschränken und ihn (Kernel) höchstens portabel halten.

Zitat von: erik
Alles was ab (einschließlich) dem Syscall passiert liegt auf dem Kernel-Mode-Stack und das sind in erster Linie die Register die die CPU automatisch dort hin legt und jene die Du dazu legst damit der Kernel selber erst mal ein paar Register zur Verfügung hat.
Naja, also zu erst hätte ich auf x86 gerne alle Register zur Verfügung (da sind so wenige und der Compiler will es so) und dann besteht der Kernel Code auch nur aus C-Code (oder welcher Sprache auch immer) und der benötigt einen Stack (den Kernel-Mode-Stack).
Da mein Kernel unterbrechbar ist, kann mitten in der Bearbeitung des Syscalls ein Interrupt kommen (kann auch ein Gerät sein) der den Scheduler aufruft, d.h. ich müsste jetzt den gesamten Stack in den Thread-Descriptor kopieren (weil ich die Daten die da stehen ja brauche um später den Thread fortsetzen zu können), aber warum sollte ich das tun, wenn die doch schon auf dem Stack liegen?

Was mir da gerade so auffällt ist wieso oft von Kernel-Threads und User-Threads gesprochen wird. Für mich war das immer das gleiche, aber es scheint wohl doch für viele einen Unterschied zu machen ob der Kernel im Kernel-Mode auch Threads haben kann (was für mich immer außer Frage stand).

Zitat von: erik
Wobei ich trotzdem der Meinung bin das mein Konzept (auf der libc-Ebene) weniger vom üblichen Weg abweicht als wenn read einen Pointer zurück gibt.
Irgendwie kommst du darüber nicht hinweg ;)

Was mir (und bestimmt auch uns was die Diskussion betrifft) weiterhelfen würde, wäre wenn jemand nen Mikrokernel kennt (der aber auch wirklich fast alles bis alles im UserSpace macht) wo der Source verfügbar ist. Damit man einfach mal gucken könnte wie andere sowas gelöst haben.

Zitat von: erik
Hä, genau das ist doch der Vorteil meiner Methode, nichts muss blockiert oder unterbrochen werden nur weil eine Message empfangen wurde (es wird ja ein neuer Thread erstellt) oder eben keine Message kommt (es soll ja kein aktives Abholen geben).
Das Problem sehe ich halt darin, das du also irgendetwas haben müsste wo du dann hinschreibst das eine Taste gedrückt wurde, wo dann der eigentliche worker Thread dann nachguckt (könnte z.B. ne Art Bitmap sein, wo du den KeyCode setzt oder resetest, was dann per cmpxchg passieren müsste/sollte).
Mir geht es nur darum, dass das auch nicht gerade der gewohnte Weg ist und man ganz schön umdenken muss, insbesondere in richtig Multithreading und Synchronisation.

Zitat von: erik
Was hat ein Speicher-Pool mit nem Garbage-Collector zu tun? Ich würde eher sagen das mein Pool einem Slab-Allocator etwas ähnelt. Und nur weil Du Das Prinzip des Garbage-Collectors nicht magst (oder möglicherweise gar nicht verstehst) heißt das nicht das es nicht funktioniert.
Ich habe an sich gegen den Garbage-Collector nichts, aber die Umsetzungen die ich bisher erlebt haben sprechen nicht gerade für ihn (das selbe Problem hat doch auch ein Mikrokernel).
Ich wollte damit nur sagen, das ein in der Theorie gutes Konzept erstmal in die Praxis vernünftig umgesetzt werden muss und genau daran hapert es meistens.
Seiten: 1 ... 30 31 [32] 33 34 ... 43

Einloggen