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 ... 33 34 [35] 36 37 ... 43
681
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 08. September 2010, 16:41 »
Zitat von: erik
Das ist was anderes, da ist hinterher ja wieder die selbe Adresse drin (falls Du alles richtig machst)
Wie kann da hinterher die selbe Adresse drin sein? Dann würde dir das ja nichts bringen. Damit willst du ja das Alignment (und damit die Größe) feststellen. Wimre dann speichert man vorher den alten Wert um ihn hinterher wieder einzutragen.
Ich lasse mich aber gerne eines besseren belehren, aber so hatte ich die Specs verstanden.
682
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 08. September 2010, 16:01 »
Zitat von: taljeth
Hm, ich habe davon ja keine Ahnung, aber wie funktioniert PCI-Hotplugging?
Dumme Antwort, aber die PCI Specs dürften da weiterhelfen ;)

Zitat von: erik
Natürlich könnte das OS die Ressourcenzuweisung noch mal komplett von neuem durchführen aber dann würden sich einige Adressen ändern (von bereits zugewiesenen Ressourcen) und das dürfte unangenehme Nebenwirkungen haben (vor allem weil es sich ja um wichtige Boot-Geräte handelt).
Warum sollte das unangenehme Nebenwirkungen ergeben? Oder um es anders zu Sagen, du wirst die Adresse/IO-Port mind. einmal ändern und zwar von jedem Gerät. Nämlich dann wenn du rausfinden willst wie groß der benutzte Bereich des Geräts ist. Da schreibt man üblicherweise 0xFFFFFFFF in das BAR um zu sehen, ob MMIO oder IO-Port und wie groß der Bereich halt ist. In dem Moment änderst du aber auch die Adresse.
Es ist also durchaus vorgesehen, das du das ganze selbst machst und taljeth Frage geht ja auch in die Richtung.

Zitat von: erik
Schon um jedem PCI-Gerät die richtige PCI-Geräte-Adresse, also Bus/Device/Function, zuzuweisen muss man den gesamten PCI komplett traversieren (durch alle Bridges hindurch).
Was hat das mit den Ressourcen zu tun? Zumal ich mir nicht mal sicher bin, das du (als OS) da noch was dran ändern kannst.
683
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 08. September 2010, 10:08 »
Zitat von: erik
PS.: Ihr streitet Euch um nichts!
Bis einer weint ;)

Zitat von: erik
die Ressourcen werden vom BIOS zugewiesen
Jein! Du kannst das im BIOS auch ausstellen (die Option heißt meistens "is a Plug&Play OS available") und dann müsste das vom OS gemacht werden, aber das wäre wirklich schlecht. Denn das würde einige Schwierigkeiten bedeuten (aber erst wenn soviel RAM vorhanden ist, das welcher davon von MMIO benutzt werden muss).

Was das "Proben" betrifft, wird von meinem OS dann einfach nicht unterstützt (ein paar Altlasten kann ich schon über Bord werfen).

Was mir aber noch nicht beantwortet wurde, gab es schon zu ISA Zeiten MMIO? War dafür nicht die Lücke im RAM zw 15MB und 16MB?
684
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 07. September 2010, 20:15 »
Zitat von: svenska
Ich will dich sehen, wie du es in einer Anwendung (nicht Treiber!) hinkriegst, jede zweite physische Speicherseite zu belegen. Im virtuellen Adressraum spielt das schließlich überhaupt keine Rolle.
Hab ich dir doch geschrieben, wenn du bei meinem (ich weiß nicht wie das andere OSs machen) als Anwendung direkt nach dem Booten, wo der Speicher noch nicht fragmentiert ist, den ganzen physischen Speicher mappst. Dann kannst du davon ausgehen, das ein Großteil davon zusammenhängend ist. Einfach weil der PMM den Speicher so rausgibt. Ich suche ja die erste freie Page und wenn du aufeinanderfolgend dann ist der Speicher der rausgegeben wird halt zusammenhängend.

Zitat von: svenska
Wenn du damit zufrieden bist, dass du damit keine DMA-Zugriffe jenseits der 4K mehr garantieren kannst, dann stimmt das. Ich behaupte, es gibt Hardware, die größere DMA-Zugriffe braucht. (Und sei es die Netzwerkkarte, die einen 8K Jumbo-Frame wegspeichern will.)
Ich habe ja auch geschrieben "nicht unbedingt". Soll heißen, wenn ein Treiber das unbedingt benötigt, muss er sich bei der Initialisierung einen Cache anlegen der die Bedingungen erfüllt.

Zitat von: svenska
Aber du magst mir nicht glauben.
Ich sags mal so, ich lasse mich gerne eines besseren belehren, aber dann möchte ich das auch schwarz auf weiß ;)

Zitat von: svenska
Es gibt nunmal Geräte mit festen Adressen. Dazu gehören ISA-Geräte, aber auch CPU-interne Geräte. Fertig.
Ich bin mir jetzt nicht sicher, aber gab es MMIO schon zu ISA Zeiten? Das einzige was da war, war doch das "Loch" zw. 15MB und 16MB oder?
Selbst wenn, dann kann ich da doch trotzdem in ein Skript eintragen und dem Treiber zuweisen.

Zitat von: svenska
Was du prinzipiell vergisst, ist, dass du bei Geräten mit Spezialzweck (z.B. Navis) nur eine Serie hast, die du zuschneiden kannst. Das Problem ist bei MIPS noch viel schlimmer, aber grundsätzlich musst du manchmal proben (oder dich auf Tabellen verlassen), eben weil nicht jedes Bussystem auch einen Devicetree erzeugen kann!
Ich kann dir nur das gleiche sagen, was ich auch schonmal erik gesagt habe, ich (und ich denke die Mehrheit der Anderen auch) schreibe ein "normales" (á la Windows/Haiku) OS und kein OS für irgendwelche Spezialhardware (wie z.B. ein Navi) und dann kommt noch hinzu das ich mich fürs erste auf die (veraltete) x86 Architektur beschränke und selbst wenn es mal soweit kommen sollte, wird wahrscheinlich "nur" ARM hinzukommen.
Selbst dann lässt sich das wunderbar mit einem Skript lösen und den Devicetree brauch ich doch gar nicht, genau deswegen will ich doch ein Skript haben.

Zitat von: svenska
Der Buffer für Netzwerkkarten ist jedoch dem System nicht unbedingt bekannt und/oder unterliegt Restriktionen der Hardware und/oder kann bei mehr RAM größer & effizienter gestaltet werden.
Hier würde ich halt auch gerne mal ne Quelle, wie eine Dokumentations sehen wollen. Denn an und für sich, müssten alle (und ich meine wirklich alle) vom Gerät verwendeten Ressourcen im PCI-ConfigSpace (ISA ist mal außen vor) stehen.
Ich habe mich mit Netzwerktreibern noch nicht wirklich beschäftigt, aber hat die Netzwerkkarte wirklich einen Buffer, den sie selbst zur Verfügung stellt und der nicht im PCI-ConfigSpace steht?

Zitat von: svenska
Also abstrahierst du das Bussystem. Einfache Systeme kennen keine Devicetrees, also musst du in der Lage sein, einen Treiber auch nachträglich zu laden - und ihm mitzugeben, wo er das Gerät findet. Solche Geräte, die nicht bereits initialisiert wurden (das betrifft beim PC z.B. auch sekundäre Grafikkarten, die nicht gebootet wurden!), müssen vom Treiber initialisiert werden - nicht vom Device-Server - und das betrifft insbesondere auch die Datenkommunikation mit dem Gerät.
Kann sein das ich hier einfach noch mit Unwissenheit glänze, aber sollte (um dein Bsp. aufzugreifen) nicht die 2. Graka auch bei der PCI Enumeration gefunden werden und somit sind ihre Ressourcen bekannt? Zumal was hat das Initialisieren mit den Ressourcen zu tun?

Ich gehe jetzt davon aus, das man entweder eine Möglichkeit hat, alle Geräte dynamisch zu "parsen" oder das alle Geräte, samt Ressourcen, vorher bekannt sind.
Wenn ich diese beiden Möglichkeiten betrachte reicht meine Skript Variante vollkommen aus. Selbst wenn der Treiber erst nachgucken (also proben) müsste ob ein Gerät vorhanden ist, dann könnte man diesen (den Treiber) mit allen möglichen Ressourcen doch in dem Skript eintragen.

Zitat von: svenska
Aber ich schreibe wahrscheinlich eh gegen ne Wand.
Wenn deine Argumente überzeugend sind, dann nicht ;)
685
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 07. September 2010, 11:20 »
Zitat von: svenska
Und wenn er die Daten nicht aus dem PCI ConfigSpace bekommt, dann vielleicht aus der Dokumentation des Prozessors (z.B. Samsung S3C2410)
Wenn der die Daten nicht von dort bekommt, dann kannst du das Gerät wegwerfen ;) Denn du wirst dann keine Probleme haben einen PC zu finden der mit diesem Gerät nicht funktioniert. Bei PCI Geräten sollten fixe Adressen eigentlich Vergangenheit sein.

Zitat von: svenska
- tut mir Leid, wenn ich darauf rumhacke, aber ich denke halt bissl weiter als nur PC-Plattform. Die finde ich inzwischen komplett überholt, mitsamt x86...
Sorry, wenn ich das mal so sage, wird von Assembler auch schon seit Jahrzenten behauptet und es wird immernoch benutzt. Dazu kommt, das wir hier (wenn nicht extra genannt) von x86 ausgehen.

Zitat von: svenska
Es geht hier nicht um Speicher - es geht um physischen Speicher. Auf den hat eine Anwendung keinen Einfluss und auch keinen Zugriff, sollte im Normalfall nichtmal in der Lage sein, solche Adressen zu erhalten! Treiber sollten hingegen mit entsprechenden Privilegien ausgestattet sein, sodaß diese mit höherer Wahrscheinlichkeit eben nicht mit den getPhysMem-Funktionen spielen.
Du willst mir also erzählen das dein PMM irgendwelche zufällig ausgewählten Seiten herausgibt? Wenn auf meinen OS nur eine Anwendung läuft und so viel wie möglich Speicher anfordert, dann kannst du davon ausgehen, das der so ziemlich zusamenhängend rausgegeben wird und das ist kein Bug, das ist nunmal so, kurz nach dem Start.

Zitat von: svenska
Ich meinte an der Stelle, dass, wenn jede physische zweite Speicherseite belegt ist - aus welchen Gründen auch immer - der User halt mal ein paar Anwendungen schließen muss.
Genau da wiederspreche ich dir ;) Es kann doch nicht sein, das wenn ich 1GB RAM frei habe, dass ich ne Meldung bekomme "nicht genügend Speicher". Da läuft dann wirklich was schief!

Zitat von: erik
Es gibt bei halbwegs moderner Hardware absolut keine Notwendigkeit physischen Speicher zusammenhängend zu allozieren! Heutzutage gibt es das Zauberwort "Scatter/Gather", das seit Jahren jeder Hersteller von irgendwelcher PCI-Hardware in die Prospekte schreibt (in letzter Zeit hat das wieder nachgelassen weil langsam alle wissen dass das jeder kann).
Auf der einen Seite gut, nur blöd das ich auch alte Hardware unterstütze ;)

Also um es festzuhalten, zusammenhängenden physischen Speicher braucht man nicht unbedingt.

Und ich gehe mal davon aus, wenn der Treiber nur die PTs von seinem UserSpace sieht, sollte das auch kein Problem darstellen!?

Edit::

Zitat von: svenska
tut mir Leid, wenn ich darauf rumhacke, aber ich denke halt bissl weiter als nur PC-Plattform. Die finde ich inzwischen komplett überholt, mitsamt x86...
Was mir noch eingefallen ist, ich denke du denkst noch zu sehr "Linux" ;)

Wenn du von festen Adressen ausgehst, die der Treiber entweder durch ausprobieren rausbekommt oder die man beim Kompilieren festgelegt hat, was bringt dir das?
Als Bsp. mal die ganzen ARM-Boards, es ist immer die selbe CPU und viele zusätzliche Geräte sind auch gleich, aber die MMIO Adressen sind anders, d.h. bei Linux, für jedes Board muss der Kernel/Treiber neu komiliert werden, nur weil ein paar andere Geräte und ein paar andere Adressen vorhanden sind?! Was bitte soll das, das ist in meinen Augen unfug und alles anders als modern!
Ich habe meinen Device-Server auch im Hinblick auf solche ARM-Boards geplant, nämlich das der Treiber die Ressourcen zugewiesen bekommt. Was ich damit erreichen möchte ist, dass du für jedes neue Board nicht den Kernel oder den Treiber neu kompilieren musst, sondern das du einfach nur ein Skript änderst wo alle Geräte und Adressen (für das jeweilige Board) drin stehen. So kann ich einfach mein OS nehmen, ohne es neu kompilieren zu müssen und kann durch ne kleine Änderung an einem Skript mein OS auf nem neuen Board lauffähig machen. Das nenn ich vernünftig, modern und im Hinblick auf andere Architekturen entwickelt!
686
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 21:29 »
Zitat von: svenska
Wenn aber jedes Programm (oder auch jeder Treiber) jederzeit nachschauen kann, wo im physischen  Speicher irgendwelche Systemteile rumliegen, dann kann er diese auch überschreiben. Das ist wiederum eine Sicherheitslücke. Oder andersrum: Es gibt Exploits für Netzwerkkartentreiber (Angriff via Netzwerk, also von remote), um Code im Kernelmodus zur Ausführung zu bringen. Basiert aber darauf, dass der (gehackte) Netzwerkkartentreiber die physischen Adressen des Kernels kennt und per DMA überschreiben lässt. (Im speziellen Falle irgendwie 4-16 Bytes je nach Zusammensetzung des Pakets und daher recht umständlich, aber geht.) Das Mapping von physisch nach irgendwo ist also zuviel Information und wird ohnehin nicht gebraucht.
Nur um dem nochmal was entgegen zu setzen ;)

Ich bi mir nicht sicher (und zu faul nachzugucken) ob ich es nicht schonmal erwähnt habe, aber ich würde dem Treiber nur gestatten die PTs zu parsen die den UserSpace betreffen. Somit kann er auch nicht in den KernelSpace gucken, aber das ist doch logisch!

Zitat von: svenska
Die Ressourcen, die ein Treiber möchte, sollte man ihm schon geben können, wenn sie denn noch frei sind - denn der Treiber muss ja wissen, welche Ressourcen die Hardware nun gern hätte. Genau diese Information möchtest du aber dem Bussystem entnehmen. Ich glaube nicht, dass das in jedem Fall funktioniert. (Bspw. sind manche Hersteller dafür bekannt, im PCI-Konfigspace komisches Zeugs stehen zu haben, was da nicht unbedingt hingehört.) Andererseits gibt es wieder Silicon Bugs, um die der Treiber evtl. herumarbeiten muss.
Also erstens, wenn er die Daten nicht aus dem PCI ConfigSpace bekommt wo soll er seine Adressen sonst herbekommen? Und das nächste Problem ist, was passiert wenn der Speicher den der Treiber (angeblich) will mit physischen RAM hinterlegt ist? Selbst wenn der Speicher gerade nicht in Benutzung ist, finde ich das doch eher problematisch.
Aber im Endeffekt ist es natürlich egal, selbst wenn man ihm die Ressourcen zuweist, kann er das System durch DMA zum Absturz bringen.

Zitat von: svenska
Dein Ansatz, bei fragmentiertem physischem Speicher einfach die DMA-Zugriffe zu verteilen und dann virtuell einen zusätzlichen linearen Cache anzulegen, bringt wenig. Die Anwendungen müssen die Daten ohnehin im Block kriegen, da ist es auch einfach sinnvoller, es gleich im physischen Block zu reservieren und das zu übergeben. Sparst du dir einmal das Kopieren der Daten. Alternative: Ich habe nicht verstanden, was du meintest.
Da hast du mich tatsächlich nicht verstanden. Ich meine das genau anders herum. Ich meinte das du einen Cache (mit zusammenhängendem Speicher) anlegst und dort per DMA reinschreiben lässt und dann in neuen (nicht zusammenhängenden Speicher) Speicher kopierst.
Aber wenn ich mir das Kopieren ersparen will (ich bin immernoch der Meinung dass das gerade beim Laden von langsamen optischen Speichern nicht wirklich was ausmacht) dann wird halt einfach in 4KB Blöcken geladen.

Zitat von: svenska
Außerdem musst du deine Speicherverwaltung schon hinreichend verkorkst haben, dass du physisch jede zweite Page belegt hast und die dazwischen nicht.
Wie kommst du darauf? Wenn du weißt wie ein Speichermanager funktioniert, dann kannst du die Situation bestimmt herbei führen. Ich sag mal so, so viel Speicher wie möglich anfordern und dann jede 2. Page wieder freigeben, sollte nicht das Problem sein und wenn das dann auch noch direkt nach dem Booten passiert, sollte die Wahrscheinlichkeit nicht schlecht sein, das du zusammenhängenden Speicher bekommst.

Zitat von: svenska
Dann muss der User halt mal was ändern.
Genau da liegt ja das Problem, der kann nichts ändern, das muss der Programmierer machen. Was willst du als User denn machen wenn irgendein Programmierer bei einem Treiber geschludert hat und dein System ständig zum Absturz bringt?
687
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 20:46 »
Jap, muss dir recht geben, macht auch mehr Sinn, denn die virtuellen Adressen sind linear = zusammenhängend, aber die physischen müssen es nicht sein.

Scheiß Haarspalterei ;)
688
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 20:18 »
Naja, da wir aber auch von Flat-Memory ausgehen/reden ist der lineare Adressraum = 4GB. In dem Fall kann man also rein theoretisch linear und physisch gleichwertig verwenden.

Bei meiner Erklärung ist es aber einfacher zwischen wirklich vorhandenem RAM und einfach nur dem Adressraum zu unterscheiden ;)
689
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 19:55 »
Zitat von: svenska
Darum würde ich das auch komplett weglassen. Wichtig ist nur, dass keine Ressource von zwei  Treibern angefordert wird, weil dann ist etwas faul. Wenn somit jede Hardware ihren Treiber hat, kann kein neuer Treiber mehr Unfug machen. Nicht elegant, aber besser als garnichts.
Also entweder ganz oder gar nicht ;)

Wenn ich schon kontrolliere das solch Speicher nicht zweimal vergeben wird, dann kann ich auch kontrollieren (weil ich eh einmal dabei bin) an wenn er gegeben wird. Das selbe mach ich ja schon bei den IO-Ports.

Was ich eigentlich erreichen möchte ist, dass der Treiber ansich nur ein paar IO-Ports oder einen SharedMem-Bereich bekommt und ansonsten eigentlich gar nicht weiß wo das alles liegt.
Sprich am besten wäre es wenn der Treiber einfach immer bei Port 0 anfangen würde und man das ganze dann per Exception abfängt und den Port 0 auf den ersten Port des Gerätes "umleitet". Da dass aber zu kostspielig ist, mach ich es über die IO-Bitmap.
Was ich aber auf jeden Fall haben möchte ist, das nicht der Treiber entscheidet welche Ressourcen er gerne haben möchte, sondern das ich (Kernel oder Server, ist ansich egal) ihm sage, so die Ressourcen sind deine und an andere kommst du nicht ran.

Zitat von: svenska
Was davon jetzt auf PCI zutrifft und was nicht, weiß ich nicht.
Also soweit ich die PCI Specs verstanden (und gelesen) habe, sind weder die Adressen von MMIO (wo ich auch nen Framebuffer dazu zähle) noch die IO-Ports fixed, sondern können festgelegt werden (aber man muss sich an bestimmte Alignments halten).

Zitat von: svenska
Wenn dein RAM physisch fragmentiert ist, hast du halt Pech.
Sorry, aber mit der Einstellung kommst du nicht weit und genau dafür wurde ja Paging "erfunden", nur dass das bei DMA nicht funktioniert (bzw. kann ich mich erinnern, das es Geräte gibt wo du auch immer 4KB Blöcke reinschreibst und das Geräte dann die Daten da hinkopiert, so wird das Problem umgangen).

Zitat von: svenska
Ich kann mir irgendwie nicht vorstellen, dass dir das BIOS jeglichen Speicher, den eine Hardware benutzen mag, schon vorgekaut als Liste gibt... die Arbeit, sich die Adressräume einzuteilen, obliegt doch eigentlich dem Betriebssystem.
Da hast du mich falsch verstanden. Das BIOS legt die MMIOs und Framebuffers möglichst perfekt an das Ende des linearen Adressraumes. Ansonsten müsstest du alle PCI Geräte enumieren und anhand von ausprobieren (wieviele Ports, wie großer MMIO Raum) diesen Speicher/Ports festlegen und das ist nicht so einfach.

Zitat von: svenska
Warum sollte der HDD-Treiber den gleichen RAM zweimal verbrauchen, nur weil du ihm keinen Block garantieren wolltest? In dem Moment hast du einen Cache am Stück und die Daten tauchen dann in 25 verschiedenen Speicherseiten auf und werden dorthin zusammengepopelt, ehe die Daten an deine Anwendung übergeben werden.
Hier habe ich wieder gar nicht verstanden was du meinst bzw. was du von mir willst ;)

Zitat von: svenska
der Netzwerktreiber muss nicht wissen, wo der HDD-Treiber die Sektoren hinspeichert. Was man mit dem Wissen machen kann, hatte ich oben schon geschrieben. Ist halt ne grundsätzliche Sache.
Da ist irgendwie ein Fehler drin! Bei einem Mikrokernel ist jeder Treiber ein eigenständiger User-Prozess. Der Netzwerktreiber bekommt also gar nicht raus wo der HDD-Treiber seine Sektoren hinspeichert! Der Netzwerktreiber kann nur innerhalb seines Prozesses gucken welche physische Adresse zu einer virtuellen gehört.

Zitat von: svenska
Was man mit dem Wissen machen kann, hatte ich oben schon geschrieben. Ist halt ne grundsätzliche Sache.
Sprich wenn obiges Problem nicht besteht kann man das mit dem Parsen so machen?!

Mal was anderes, wie kommt es das du hier ein Sicherheitsproblem siehst, bei der Sache ob ein Treiber aber falschen Speicher mappt nicht?
690
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 18:40 »
Zitat von: svenska
Du traust also dem Treiber zu, dass er nicht DMA auf "irgendwelchen" Speicher in die Hardware schreibt, traust ihm dann aber wieder nicht zu, dass er sich Speicher holen darf, den er braucht?
Naja, wenn du so ran gehst, dann brauchst du für einen Treiber gar keine Sicherheit! Wozu kontrollieren auf welche Ports der Treiber zugreifen darf?
Ich will, soweit es geht, ein wenig Sicherheit auch vor Treibern. Das ich mich nicht vor falschen DMA Adressen schützen kann, ist leider schade, aber damit muss ich leben.
Da ist der alte ISA DMA Kontroller natürlich besser zu kontrollieren. Denn den könntest du noch abstrahieren und selbst kontrollieren und die Treiber müssten dann alle DMA Anforderungen an dich (als z.B. Server) machen.

Zitat von: svenska
Damit weißt du also, welcher Teil des physischen Speichers wo im virtuellen Speicher eines jeden Prozesses gemappt ist.
Mein Problem hier ist, meinst du damit auch, dass ich wissen müsste in welchem Prozess die Page 0x1000 ist? Denn das könnte ich zwar rausbekommen, aber nur ziemlich umständlich indem ich von jedem Prozess die PTs einblenden müssten (in den Kernel) und die PTs dann nach der Page durchsuchen müsste. Bis das alles fertig ist, kann die Page schonwieder in einem ganz anderem Prozess sein (zwecks Swapping).

Zitat von: svenska
Teile des physischen Adressraums sind nicht mit Speicher unterlegt, sondern mit Konfigurationsregistern der Hardware, meist jenseits des realen RAM-Ausbaus (z.B. jenseits der 2GB). Dort muss ein Treiber also unter Umständen physischen Adressraum in seinen eigenen virtuellen Adressraum mappen, der kein RAM ist.
Was du meinst ist linearer Adressraum und virtueller Adressraum! Physischer Speicher (wie der Name schon sagt) ist wirklich vorhandener RAM!
Und wenn du auf einem 32bit System 4GB RAM hast, dann belegt auch MMIO physischen RAM, was halt weniger schön, aber unvermeidbar ist.

Zitat von: svenska
Wo die Adressen im virtuellen Adressraum landen, ist egal. Welche Adressen im physischen Adressraum benutzt werden, hängt konkret von der Hardware ab (Konfigurationsregister sind fest) und ist nur teilweise programmierbar (Zieladresse des DMA ist es).
Da liegst du falsch. Denn die MMIO Adressen von PCI Geräten kann man sehr wohl selber bestimmen oder wie meinst du funktioniert das!? Eigentlich macht das BIOS diese Verwaltung, aber wenn es das nicht macht, müsstest du es selber machen und genau das ist momentan bei mir nicht möglich (da ich noch nichts habe, um bestimmte Pages im PMM als benutzt zu markieren).

Zitat von: svenska
Wie gesagt, Teile des physischen Adressraums, den du benötigst, sind nicht mit RAM unterlegt.
Wie oben geschrieben, stimmt das leider nicht immer.

Zitat von: svenska
Wenn der Treiber physisch 4 MB RAM unterhalb der 16 MB fordert (weil es halt ein popeliger ISA-SCSI-Controller ist), dann wird das wahrscheinlich nicht gehen. Wenn du aber gerne physisch 4 MB RAM als Block irgendwo möchtest, dann geht das wahrscheinlich schon. Ist der RAM voll, dann geht das eben nicht. Wie auch?
Deswegen macht es z.B. Linux auch so, dass so lange wie freier Speicher >16MB vorhanden ist, wird dieser genommen und somit kann der Speicher <16MB für ISA Treiber genutzt werden. Bei meinem Bsp darf das also nicht passieren.
Mir geht es auch nicht darum das der RAM voll ist, sondern das er fragmentiert ist!

Zitat von: svenska
Außerdem sollte der Treiber für die Kommunikation mit dem Gerät den Speicher direkt beantragen, oder zumindest einen kleinen Block (z.B. 64 KB). Damit garantierst du auch bei voller Speicherauslastung, dass du die Hardware ansteuern kannst.
Ich habe mir das für ISA Geräte so vorgestellt, das sie immer "nur" 64KB Speicher bekommen (davon wird es 8-10 Blöcke geben) und mit diesem Block dann auch auskommen müssen.

Aber die Idee kann ich auch auf andere Treiber übertragen. Problematisch wären dann aber Systeme mit wenig RAM (im Moment soll mein OS auch mit 8MB klar kommen), wo man nicht einfach mal sagenkann , ich benutze jetzt immer 4MB um die Daten von HDD in den Speicher zu bekommen und kopiere die Daten dann in SharedMem.
Was man machen könnte, ist je nach Speicherausstattung einen Cache bei der Initialisierung anzulegen.

Zitat von: svenska
Was nicht ausreicht, da der physische Adressraum halt 4GB groß ist und du dort (z.B. ab 3GB) den Framebuffer der Grafikkarte oder die PCI-Konfigurationsregister findest. Die musst du auch verwalten!
Im Moment gehe ich noch davon aus, dass das BIOS diese Arbeit für mich schon gemacht hat, aber ich werde mir wohl nochmal was einfallen lassen müssen wie ich es mache, wenn das nicht der Fall ist. Wobei hier dann auch die Frage aufkommt, wie bekomme ich raus, dass das BIOS die Arbeit schon gemacht hat?

Zitat von: svenska
Was hat dein Treiber davon, wenn er sich jede einzelne Page, die er für die Kommunikation mit der Hardware braucht, einzeln anfordern muss? Außerdem garantierst du ja nicht, dass die Pages zusammenhängend sind.
Der Treiber fordert ja nicht jede Page einzeln an, sondern er muss für jede Page einzeln nachgucken welche physische Adresse dahinter steckt und das genau wegen dem Grund, dass die Pages nicht zusammenhängend sein müssen (es bei der Initialisierung aber höchst wahrscheinlich sein werden).

Zitat von: svenska
Erklär du mal dem HDD-Controller, dass er die ersten 4 KB nach 0x3400 0000, die zweiten 4 KB nach 0x3800 0000 und die dritten 4 KB nach 0x3400 8000 schreiben soll. Das heißt, du programmierst die Hardware dreimal, um 12KB von der Festplatte zu lesen.
Im schlimmsten Fall, ja ;) Aber bevor es soweit kommt, würde ich halt sagen, der Treiber guckt wieviel RAM das System gesamt hat und legt sich danach einen Cache an (für DMA) und damit ist das Problem dann auch gegessen. Obwohl es gerade bei der HDD nicht die Welt sein sollte, für jede Page eine neue Anfrage zu machen, da ersten die Datei sowieso fragmentiert sein könnte (dann musst du das eh machen) und die Festplatte so "langsam" liest das sich an der absoluten Zeit nicht viel ändern wird.

Zitat von: svenska
Implementier lieber zwei Funktionen:

*getPhysMem( int size, ptr physAddr )
-> gib mir "size" Bytes ab physisch "physAddr" zurück
=> malloc() mit gegebener Adresse für deinen PMM

*getPhysMem( int size, ptr *physAddr )
-> gib mir "size" Bytes Speicher und schreibe in "physAddr" die physische Adresse rein
=> malloc() mit Rückgabe der verwendeten physischen Adresse
Also beide Funktionen haben schonmal das Problem (was aber auch nur meiner Sichtweise entspricht) das sie mit "Bytes" arbeiten, aber die Größe eigentlich auf 4KB Blöcke beschränkt ist.
Dann habe ich bei der ersten Funktion noch das Problem, versuche das mal bei einem PMM der mit nem Stack arbeitet!
Die 2. Funktion ist da schon eher was für mich, aber siehe weiter unten.

Zitat von: svenska
Wenn du willst, kannst du noch einen Alignment-Parameter mit einbinden, wenn du z.B. Hardware hast, die ein Alignment >4K braucht.
Gibt es sowas (also wo die Adresse wo das Gerät hinschreiben soll ein Alignment >4K brauch)? Das wäre ein echtes Problem :(

Zitat von: svenska
Was du dir sparst:
- Prozesse müssen die PageTables nicht selbst parsen können (Portabilität, vgl. taljeth)
- Prozesse haben keine Möglichkeit, das Mapping zwischen virt. und phys. Adressraum rauszukriegen (Sicherheit)
- nur ein Syscall pro Treiber und Adressraumblock
Was die Portabilität betrifft, siehe meine Antwort darauf und auch muss es der Treiber nicht selbst könne (siehe selbe Antwort).
Mir hat noch keiner eine wirkliche Antwort gegeben wo das Sicherheitsproblem wäre, wenn der Treiber die PTs parsen könnte.
Beim Parsen der PTs hätte ich auch nur einen Syscall.
691
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 17:07 »
Zitat von: PorkChicken
Zwischen Lesen und Verwenden der physischen Adresse (z.B. Versenden an die HW) kann eine gewisse Zeit vergehen, in der sich das Mapping ändern kann (Swapping, Copy-on-Write, verzögertes Mapping, MMIO, etc.) Dagegen hilft nur Locking, Pinning, ... wie auch immer man das nennen will. Auf jeden Fall musst du die Zuordnung auf die physischen Adressen in einen definierten Zustand bringen, was dich Syscalls kosten wird.
Würde ich einfach als Flag ("UNSWAPABLE") implementieren, welches dann natürlich nur von Treibern benutzt werden darf, bzw. da ich ohnehin plane solche Buffer dann als SharedMem an andere Prozesse weiterzugeben wäre das Problem auch so gelöst (SharedMem wird bei mir auf keinen Fall ausgelagert).
692
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 16:43 »
Zitat von: taljeth
Den Syscall brauchst du doch sowieso, damit du überhaupt Speicher bekommst, auch wenn er nur virtuell zusammenhängend ist?
Ja, ich meine aber das:

- Du forderst 64KB an
- bekommst eine virtuelle Adresse zurück
- jetzt machst du für jede 4KB Page einen Syscall um die physische Adresse rauszubekommen

Was man machen könnte, ist einen extra Syscall für Treiber zu implementieren, dem man einen Pointer übergibt, wo man die physischen Adressen des virtuellen Speichers (der angefordert wurde) reinschreibt.

Zitat von: taljeth
Und außerdem würde die PT direkt lesen bedeuten, dass jeder Treiber das Page-Table-Layout kennen muss. Das gibt einen Spaß beim Portieren.
Portabler Code ist nicht wirklich eins meiner Ziele (auch wenn ich es im Hinterkopf habe). Dazu kommt noch, was ist an "getPhysAddr(void *virtAddr)" unportabel? Ich meine, du lagerst das einfach in eine Funktion in einer Bibliothek aus und wie das dann in der Bibliothek implementiert ist, kann dir doch egal sein.

Mein Frage wäre bzw ist noch immer, ob durch das Lesen der PTs wirklich ein Sicherheitsproblem entsteht?

Wie wird der ganze Spaß denn in anderen Mikrokerneln gelöst (rausbekommen welche physische Adresse hinter einer virtuellen steckt)?
693
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 16:15 »
Zitat von: taljeth
Kann ich nicht, der Kernel hat keine Ahnung von PCI (oder was auch immer). Klassische Lösung: Alles was als root läuft (oder sonst irgendeine Art von Recht hat), darf das.
Und genau das möchte ich bei mir nicht, mit Ports ist das noch relativ einfach und wenn ich eine Möglichkeit gefunden habe, bestimmten Speicher nur in meinem Device-Server zuzulassen, dann habe ich auch das Problem gelöst (ich "vererbe" den Speicher dann einfach an die Treiber, das wäre die Lösung für MemoryMapped-IO).

Zitat von: taljeth
Das ist doch genau der Fall, den ich beschrieben habe?
Nur, will ich das der Speicher nicht unbedingt zusammenhängend sein muss und dann müsste man einen Syscall pro Page machen und das wäre mir halt doch ein wenig zuviel des Guten (würde aber für den Anfang funktionieren) und deswegen dachte ich daran, einfach den Treiber lesend auf die PageTables zugreifen zu lassen.

Zitat von: taljeth
Mit virtuell zusammenhängend kann die Hardware aber dummerweise nichts anfangen. Wenn du nicht mehrere Pages physisch zusammenhängend zur Verfügung stellen kannst, musst du dich eben einschränken und maximal 4k auf einmal an die Hardware übergeben.
Genau so ist das geplant. Die einzige Möglichkeit an zusammenhängenden physischen Speicher zu kommen, ist es 4MB "direkt", also eine 4MB Page, (mein PMM unterstützt das ab 32MB RAM) anzufordern.

Zitat von: svenska
Dein Memory Manager hat den Überblick über den gemappten physischen Speicher.
Was meinst du genau mit "gemappten physischen Speicher"? Meinst du da welcher Speicher in Benutzung ist und welcher nicht?

Das kann mein PMM nicht so richtig. Ich weiß welcher Speicher frei ist, aber mehr auch nicht.

Zitat von: svenska
Außerdem, wenn ich physischen Speicher möchte, ist es mir ja erstmal egal, wo der liegt - die Adresse kann ich dann ja in die Hardware reinprogrammieren.
Wenn wir jetzt über MemoryMapped-IO reden, dann ist es unter Umständen nicht egal wo dieser physische Speicher liegt, bzw. sollte hinter einer MemoryMapped-IO Adresse (im besten Fall, wo also weit weniger als 4GB RAM vorhanden sind) kein physischer Speicher liegen, das Alignment macht dir nämlich einen Strich durch die Rechnung.
Soweit kommt es aber bei mir noch nicht, da ich noch keine Möglichkeiten habe, den Speicher für MemoryMapped-IO selbst zu bestimmen. Dazu müsste ich gezielt Speicher aus meinem PMM entfernen können.

Zitat von: svenska
Dann geht das halt nicht, ganz einfach. Wenn mein Gerät DMA machen möchte, muss ich mindestens einen DMA-Block physisch zusammenhängend bereitstellen. Und wenn ich gern "schnell" hätte, muss ich halt mehrere solcher Blöcke haben - im einfachsten Fall als ein großer Block. Ist aber Sache des Treibers, wieviele Blöcke ich welcher Größe wo brauche. In meinem Beispiel sind das einfach 2 Blöcke, die müssen auch nicht hintereinander liegen.
Das ist aber schlecht! Wie willst du nem User folgendes verklickern:

er hat zwar von seinen 2GB RAM noch 1GB frei, aber da der Speicher so fragmentiert ist dass jede 2. Page (physisch gesehen) in Benutzung ist, kann er keine Daten mehr von seiner HDD laden?

Das ist aber ein ganz schlechtes Konzept. Bevor du mir jetzt mit Paging und Swapping kommst, auch für das Swapping bräuchtest du dann ja mehrere zusammenhängende (physisch) Blöcke.

@svenska

Ich weiß nicht wie dein MemoryManager funktioniert, aber ich habe einen PMM und einen VMM. Der PMM ist einfach nur dafür verantwortlich, das man freien physischen Speicher von ihm bekommt und nicht mehr benötigten physischen (also vorhandener RAM) zurückgeben kann.
Der VMM kümmert sich einfach nur darum, welche virtuelle Adresse frei ist und welche nicht.

Der Punkt ist, mein PMM verwaltet nicht immer 4GB sondern nur soviel Speicher wie da ist.
694
Lowlevel-Coding / Re:x86-64 Speicherverwaltung
« am: 06. September 2010, 15:26 »
@Programm Noob
Das ist jetzt nicht böse gemeint, aber anstatt C zu lernen, solltest du dich mal mit Assembler beschäftigen!

Spätestens wenn du verstanden hast wie ein Stack und damit auch dein C-Code funktionieren, weißt du das dein Bsp., ich sags mal nett, nicht funktionieren kann!
695
Lowlevel-Coding / Re:Treiber bei einem Mikrokernel
« am: 06. September 2010, 15:21 »
Zitat von: taljeth
Also erstmal das wichtigste: Es heißt physisch, nicht physikalisch.
Wird Zeit das ich wach werde ;)

Mit dem Konzept habe ich so meine Probleme. Wie gehst du sicher das ein Treiber auch nur den Speicher mappt der zu dem Gerät gehört? Ansonsten könnte ein Treiber ja sonstwas für Speicher mappen.
Das nächste ist, ihr geht hier nur von MemoryMapped-IO aus, ich meine aber auch, das du halt einfach sagst, ich (der Treiber) brauche mal 64kb Speicher, brauche die physische Adresse von jeder 4KB Page, damit ich da was reinladen lassen kann.

Auch finde ich es nicht passend das ihr davon ausgeht das der physische Speicher zusammenhängend ist. Erstens kann das mein PMM nicht wirklich und zweitens, was wird gemacht, wenn zwar genug Speicher, aber halt kein zusammenhängender Speicher vorhanden ist?

Zitat von: svenska
wenn ich als Bösling die physikalische Adresse einer virtuellen Adresse herausbekommen kann, kann ich mittels Buffer-Overflows etc. in den Treibern mittels DMA Codebereiche überschreiben (lassen), die dann später gezielt zur Ausführung gebracht werden. DMA kennt auch keine Sicherheitsmaßnahmen.
Sorry, aber das Problem hast du so oder so! Ich meine, man muss schon davon ausgehen, das man einem Treiber vertrauen kann. Denn wie willst du sicher stellen, das ein Treiber die HDD dazu instruiert wirklich nur in den Speicherbereich zu schreiben der dafür vorgesehen ist und nicht irgendwelchen vorhandenen Code überschreibt?

Zitat von: svenska
Treiber können dann noch eine besondere Privilegierungsstufe bekommen, sodaß normaler Userspace eben nicht den physischen Adressraum benutzen kann. Mit dieser Variante brauchen auch Treiber nicht zwischen physisch und virtuell umrechnen - das erledigt die Speicherverwaltung. Die hat die Daten eh vorliegen und kümmert sich um die Reservierungen.
Das habe ich mal gar nicht verstanden ;)
696
Lowlevel-Coding / Treiber bei einem Mikrokernel
« am: 06. September 2010, 13:34 »
Beim Thema IPC Methoden wurde es mal ganz kurz angerissen, das Thema Treiber. Bei einem Mikrokernel ist das Thema nicht so einfach.

Um was es mir aber genau geht, ein Treiber braucht oft (??) die physikalische Adresse einer virtuellen (da DMA kein Paging kennt) und das erste Problem wäre die Sicherheit, ich möchte eigentlich nicht jedem Prozess erlauben rauszubekommen welche physikalische Adresse hinter einer virtuellen steckt.

Aber was wäre das Problem wenn dem so wäre, sprich was könnte ein Prozess damit anfangen?

Ich überlege einfach die Pagingtabellen für Treiber "freizugeben", sprich die können lesend darauf zugreifen (natürlich nur auf den UserSpace-Teil). Was haltet ihr davon? Der Vorteil wäre die Performance, da dadurch Syscalls entfallen würden.

Nächstes Problem wäre, wie bekommt man den Speicher eines Geräts, z.B. den Framebuffer einer Graka, in den Adressraum des Treibers?

Das Problem was ich habe, ist das die ganzen Geräte nicht im Kernel sondern in einem Device-Server verwaltet werden und es so schwieriger wird solchen Speicher zu mappen, weil auch da wieder die Frage ist, wie bekomme ich diesen Speicher in den Device-Server?
697
Lowlevel-Coding / Re:Allgemeine Fragen zu x86-64
« am: 05. September 2010, 08:34 »
Zu Frage 1, da würde ich mal die physische Speicherverwaltung rausnehmen. Ich weiß nicht was einen Algo du dafür nutzt, aber ansich geht man ja bei 32bit System von max 4GB RAM aus (was z.B. auf Servern nicht immer korrekt ist) und von daher wirst du dort wohl auch etwas anpassen müssen.
Genauso muss das IDT verändert werden (genauso wie das GDT). Interrupts sind sowieso ein wenig anders, Thema Red-Zone.

zu Frage 3+4, guck in den Intel Manuals nach und/oder bei den AMD Manuals.
698
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 05. September 2010, 08:30 »
Zitat von: svenska
Was ich damit nur anmerken wollte, ist, dass der TSC grundsätzlich als "nicht zuverlässig" zu bewerten ist, was meine Ursprungsaussage war. Umkehrschluss heißt, dass die Zeitmessung im Bereich des TSC ungenau ist (was deinem Grundgedanken widerspricht) oder du eine Whitelist über CPUs führen musst, bei denen der TSC stabil ist.
Wenn dann wollte ich das sowieso über eine "Whitelist" machen. Interessant das es auf nem P3 noch funktioniert, aber auf nem P3-M leider nicht.

Zitat von: svenska
Einen Pentium III Coppermine (Family 6, Model 8, Stepping 10) markiert Linux nicht als "unstable TSC", meinen Core2 Duo T5500 (Family 6, Model 15, Stepping 6) und meinen VIA C7 (Family 6, Model 13, Stepping 0) jedoch schon.
Laut nem Wikipedia-Artikel (nicht das ich dem 100%ig vertraue) steht das dein Core2 Duo eigentlich schon solch einen konstanten TSC haben müsste und laut dem was ich auf die schnelle bei Google gefunden habe, funktioniert der TSC schon, halt nur nicht mehr wenn du in einen Schlafmodi <= C2 gehst und da ist ja der PC schon fast aus ;)

Ich werd dazu mal die Intel Manuels befragen.
699
Lowlevel-Coding / Re:Konzept für periodische Events
« am: 04. September 2010, 22:14 »
Erstmal willkommen zurück aus dem Urlaub.

Also das der VIA C7 keinen konstanten TSC unterstützt habe ich eigentlich erwartet, aber was mit dem Core2Duo ist weiß ich auch nicht.
Eine schnelle Suche per Google hat mich nur soweit gebracht, das es wohl was mit tieferen Schlafmodi (<=C2) zu tun hat und da beeinflusst das mein System nicht und selbst wenn, dann muss ich halt die Anforderungen für den TSC höher setzen.

Ich müsste direkt mal nachgucken wie lange es dauert aus einem Schlafmodi <= C2 wieder raus zukommen, bzw. wie groß die Zeitspanne ist da rein und wieder raus zukommen.
700
Lowlevel-Coding / Re:IPC Methoden
« am: 01. September 2010, 20:28 »
Was mir noch eingefallen ist, wenn du mal vom aktiven Abholen (so wie du es nennst, sprich wo du sagst in welchen Buffer die Nachricht soll) ausgehst, dann fällt auch Mapping flach. Denn damit Mapping funktioniert, müssen der Buffer wo die Nachricht drin ist und der Buffer wo die Nachricht rein soll das selbe Pageoffset haben, ansonsten klappt das nicht.

Wenn ich jetzt mal mit dem Gedanken spiele, das ich meinen recv-Syscall so umbaue, dass dieser mir den Buffer zurück gibt (mit der Nachricht drin), dann habe ich nur noch das Problem, was mache ich mit kleinen Nachrichten? Denn ich müsste jedes Mal mind. 1 Page allokieren um die kleine Nachricht da rein zu kopieren und eine extra Page für sagen wir 32bytes finde ich dann doch ganz schön übertrieben. Auch müsste ich mir dann was einfallen lassen wie der Empfänger (wo die Nachricht reinkopiert/rein gemappt wurde) den Speicher wieder freigeben kann. Denn ein "free(bufferOfMsg)" geht nicht, da ja der Speicher von dem UserAllocator gar nicht erfasst ist und das auch nicht möglich ist, da ich (als Kernel) nicht wissen kann, was für einen Allocator der Prozess benutzt und wo dessen Datenstrukturen sind und wie diese aufgebaut sind.

Edit::

Was mir gerade noch so durch den Kopf gegangen ist, mit synchronen IPC machst du dir auch das Leben schwer wenn es um Multithreading geht.
Wenn ich mal dein Bsp mit dem "ls" über 10000 Dateien nehme, dann könnte ich mehrere Anfragen (wenn das möglich ist, das weiß ich jetzt nicht so genau) mit einmal in meine Pipe schreiben und würde beim Versuch eine Antwort aus der anderen Pipe zu lesen blockieren. Der VFS-Service bearbeitet die erste Anfrage, packt die Antwort in die Pipe und weckt mich auf. Wenn man jetzt auf einem SMP-System ist, dann können jetzt der Client und der Service gleichzeitig auf verschiedenen CPUs laufen. Da noch Anfragen in der Pipe sind, kann der Service eine weitere bearbeiten. Gleichzeitig hat der Client die Antwort gelesen und verarbeitet und könnte jetzt eine weitere Anfrage in die Pipe schicken und wird dann nach der nächsten Antwort gucken, da ja der VFS-Service gleichzeitig lief, ist es gar nicht so unwahrscheinlich das er bereits eine neue Antwort in die Pipe geschrieben hat und der Client somit weiter arbeiten kann.
Im optimalen Fall kann das so für die ganzen 10000 Dateien laufen. Das Nachrichten senden und empfangen würde also komplett ohne Syscalls auskommen und es könnte alles Paralell geschehen. Sowas war auch ein Grund wieso ich unbedingt eine solche Pipe im UserSpace für viele Sachen nehmen will.

Was mich auch noch beschäftigt hat ist die Geschichte mit dem Datei laden. Bei einer 300MB Datei wird es unwahrscheinlich das diese von noch einem Prozess geladen wird, aber wenn wir irgendwelche kleinen Dateien nehmen dann wird es schon wahrscheinlicher.
Was ich eigentlich will, du musst die Daten der Dateien kopieren, weil du (auf jeden Fall beim Paging) ja nicht davon ausgehen kannst, dass jeder Buffer wo die Dateien so rein sollen immer das gleiche Pageoffset haben!
Wie machst du es überhaupt wenn eine Datei mehrmals geöffnet/gelesen wird? Lädst du die dann jedes Mal neu oder kopierst du in dem Fall auch?
Seiten: 1 ... 33 34 [35] 36 37 ... 43

Einloggen