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

Seiten: 1 [2] 3 4 ... 138
21
Lowlevel-Coding / Re: VESA Grafik-Modi
« am: 20. January 2017, 13:46 »
Du bräuchtest einen nativen Grafiktreiber. Je nach Karte gibt es öffentliche Dokumentation dafür oder auch nicht, aber selbst wenn es welche gibt, habe ich gehört, dass diese Dokumentation dann auch zu verstehen und umzusetzen alles andere als einfach ist.
22
Lowlevel-Coding / Re: FAR-Jump in NASM
« am: 11. January 2017, 10:25 »
ähm mit immediate-Werten meinst du sowas wie Hard-codierte-Adressen, also
jmp 0x1000:0x0000oder ?
Genau.

Zitat
Mit dem "Far Pointer im Speicher" hab ich dich nicht so recht verstanden. Meinst du damit das push es, push bx, retf ?
Wäre praktisch gesehen eine Option. Ich habe aber die Variante gemeint, wo tatsäcjhlich jmp einen Far Pointer als Operanden bekommt. Mit nasm und Real Mode kombinierst du alles, mit dem ich nicht viel Erfahrung habe, aber das würde irgendwie so aussehen:
mov [bla], bx
mov [bla + 2], es
jmp [bla]

bla:
    dw  0
    dw  0
23
Lowlevel-Coding / Re: FAR-Jump in NASM
« am: 10. January 2017, 10:49 »
Nein, ging nicht. Lies die Beschreibung zu JMP im Intel-Manual und du wirst feststellen, dass es Far Jumps nur mit Immediate-Werten oder einem Far Pointer im Speicher gibt. Was anderes kann dein Prozessor nicht, also hat nasm auch keine Syntax dafür.
24
Lowlevel-Coding / Re: Mal wieder am reinarbeiten, wo weitermachen?
« am: 23. November 2016, 12:59 »
Aha, das Standardproblem. :-D

Ja, dann flick vielleicht lieber erst mal dein Paging.
25
Lowlevel-Coding / Re: Mal wieder am reinarbeiten, wo weitermachen?
« am: 23. November 2016, 10:32 »
Die meisten bauen als erstes eine Shell, die halt Eingaben entgegennimmt und dann nutzlose Befehle ausführt (weil nützliche beim aktuellen Stand ja noch nicht gehen). So Sachen wie "echo", "version", "help" und "exit". Kann man machen, wenn man will.

Deinen Ansatz finde ich aber auch gut. Wenn du dann einen Plattentreiber und einen Dateisystemtreiber hast (read-only reicht ja für den Anfang und das geht recht zügig), kannst du immer noch eine Shell anfangen und dann gleich Sachen wie "ls" oder "cd" einbauen. Das lohnt sich dann auch halbwegs.

Für IDE brauchst du nicht zwingend PCI, IDE an sich ist nämlich älter und damals noch mit ISA benutzt worden. Für dich heißt das in erster Linie, dass du den Controller an festen I/O-Ports ansprechen kannst und die Daten dann auch über diese Ports übertragen kannst (also PIO-Modus). Später ist DMA dazugekommen und das geht dann nur über ein PCI-Gerät, aber zum einen kannst du das vorerst ignorieren, und zum anderen ist es auch nicht schwer, PCI-Geräte zu erkennen, d.h. das kannst du ohne weiteres gleich als nächsten Schritt machen, wenn dir danach ist. ACPI brauchst du schon gar nicht. Du kannst dich also direkt auf IDE stürzen.

Ich würde dir empfehlen, für den Anfang eine der älteren Spezifikationen zu benutzen, wo noch alles in einem Dokument steht, und ich es teilweise übersichtlicher finde. Du kannst dir zum Beispiel ATA/ATAPI-5 hernehmen.

Wenn du für das Dateisystem FAT nimmst, kommt es auf deine Imagegröße an, was für eine Variante du bekommst (genauer gesagt auf die Anzahl der Cluster, und weil man die Clustergröße in einem gewissen Bereich selber festlegen kannst, hast du etwas Spielraum). Für ein Plattenimage in der für ein Hobby-OS typischen Größe (mehr als 32 MB, aber nicht mehrere GB) dürfte das auf FAT16 rauslaufen. Das erspart dir FAT12, was ein bisschen eklig ist (weil 12 halt bedeutet, dass man mit halben Bytes arbeiten muss).
26
Lowlevel-Coding / Re: Festplatten Sektoren direkt einlesen
« am: 18. November 2016, 15:31 »
Wenn du Code zum Anschauen brauchst, kannst du dir mal die Treiber ata (für das alte IDE-Interface) und ahci (eben für AHCI) in CDI anschauen: http://git.tyndur.org/?p=cdi.git;a=tree
27
Lowlevel-Coding / Re: Festplatten Sektoren direkt einlesen
« am: 18. November 2016, 11:06 »
Was genau sind denn die Probleme, die deinen Treiber kompliziert und fehleranfällig machen?
28
Lowlevel-Coding / Re: Ablauf Paging
« am: 11. November 2016, 09:18 »
Hast du das mit gdb praktisch ausprobiert? gdb an qemu ranhängen kann ab und zu praktisch sein, aber über einen Kontextswitch oder Moduswechsel weg würde ich ihm keinen Meter weit trauen. Solange jemand an grundlegenden Kernelbausteinen arbeitet, ist meiner Meinung nach gdb nicht die Antwort. Das ist dann aber auch eine Größenordnung, die man selbst mit printf, Endlosschleifen, Registerdumps und Speicher anschauen noch hinbekommt.

Also anstatt einen Breakpoint zu setzen, baust du einfach eine Endlosschleife an der Stelle in den Code ein, dann weißt du hundertprozentig, dass er wirklich stoppt, und zwar an der richtigen Stelle, und kannst den Zustand auch in Ruhe anschauen.
29
Lowlevel-Coding / Re: Ablauf Paging
« am: 08. November 2016, 21:10 »
Sein lassen bringt nichts, ohne Paging kannst du kein vernünftiges OS basteln. Und aus der Ferne mit ungefähren Andeutungen rauszufinden, was passiert, ist auch nicht einfach. Da musst du dich jetzt einfach durchbeißen und lernen, wie man ein OS debuggt. Bevor du jetzt wild herumbastelst, solltest du erst einmal versuchen, herauszufinden, was genau vor sich geht, und warum das nicht das ist, was du wolltest. Und erst wenn du verstanden hast, warum passiert, was passiert, machst du dich daran, es zu fixen.

Wenn sich etwas jedesmal anders verhält, dann ist das ein Fehler. Also solltes du damit anfangen herauszufinden, wo das unerwartete/undefinierte Verhalten genau losgeht und dann siehst du auch, warum. Mit viel printf und evtl. Endlosschleifen sollte sich das rauskriegen lassen. Für schwere Fälle, in denen du gar nicht mehr weißt, welcher Code eigentlich ausgeführt wird, kannst du noch die Debug-Logs von qemu dazunehmen.
30
Lowlevel-Coding / Re: Ablauf Paging
« am: 05. November 2016, 11:03 »
Ein ungeplanter Reboot ist normal ein Tripe Fault. Das heißt, dass irgendein Interrupt (vermutlich ein Page Fault) aufgetreten ist, aber der Prozessor keinen gültigen Interrupthandler gefunden hat, dass er also entweder die IDT oder GDT nicht lesen konnte (nicht oder nicht richtig gemappt?) oder dass die Einträge darin nicht gültig waren. Danach versucht die CPU dann erst noch einen Double Fault zu melden, aber wenn auch dieser Interrupthandler nicht funktioniert, kommt es zum Triple Fault (= CPU-Reset).

Du kannst mal qemu -d int probieren, dann loggt er dir alle Interrupts mit und zu jedem Interrupt auch noch einen CPU-Dump, d.h. mit den Interruptnummern, eip und cr2 müsstest du eigentlich herausbekommen, was da genau passiert.
31
Lowlevel-Coding / Re: Ablauf Paging
« am: 04. November 2016, 22:26 »
Das ist doch die ganz normale Meldung, die bei jedem Bootvorgang kommt?

Vielleicht löschst du den Bildschirm normalerweise und siehst sie deswegen nicht, aber jetzt geht schon vorher etwas schief?
32
Lowlevel-Coding / Re: Ablauf Paging
« am: 04. November 2016, 16:04 »
Ich würde an deiner Stelle erstmal versuchen, den Teil ohne Tasks ans Laufen zu bringen. Wenn der jetzt "feststeckt", wird es sicher nicht besser, indem du noch mehr fehlerhaften Code obendrauf packst. Du tust dich leichter, wenn du einen Fehler nach dem anderen angehst.
33
Lowlevel-Coding / Re: Ablauf Paging
« am: 03. November 2016, 13:26 »
tyndur benutzt eine andere Deklaration von kernel_start:
extern void kernel_start(void);Der "Vorteil" an einem Funktionspointer ist, dass &fn == fn ist, aber man sollte besser nicht versuchen, die Funktion aufzurufen, weil an der Adresse eben keine Funktion liegt (oder zumindest nicht wirklich definiert ist, welche). Von daher finde ich das in tyndur eher unschön gelöst.
34
Lowlevel-Coding / Re: Ablauf Paging
« am: 03. November 2016, 12:40 »
#define kernel_page_tables  ((uint32_t*)(kernel_page_directory + (KERNEL_BASE >> PGDIR_SHIFT)))Wenn man es Schritt für Schritt auseinandernimmt, dann ist es gar nicht kompliziert:
  • KERNEL_BASE ist die Startadresse für den "Kernelteil" des Adressraums (also in der Praxis 0 bei tyndur)
  • KERNEL_BASE >> PGDIR_SHIFT ist dann der PD-Index, an dem der Kernelteil beginnt
  • kernel_page_directory ist ein Pointer auf unsigned long
  • Mittels Pointerarithmetik ist der gesame Ausdruck dann ein Pointer auf den ersten PDE, der zum Kernelspace gehört
Wenn man den Kernelspace irgendwo anders als bei 0 anfangen lassen würde, würde man die ganze Berechnung sogar brauchen, aber so ist
kernel_page_tables einfach das gleiche wie kernel_page_directory.

Ü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. ;)

extern const void kernel_startDas wichtige hier ist, dass kernel_start nicht eine Variable ist, die die Startadresse enthält, sondern es ist ein Symbol, das am Anfang des Kernels liegt. Das heißt, du willst nicht den (nicht existenten) Inhalt der Variable, sondern die Adresse von diesem Symbol haben: &kernel_start
35
Lowlevel-Coding / Re: Ablauf Paging
« am: 24. October 2016, 10:19 »
So, zur Adressraumaufteilung gleich meine erste Frage: Das wird nur realisiert durch entsprechend gesetzte Flags in den PTE's?
Ja. Rein theoretisch brauchst du so eine Aufteilung überhaupt nicht, sondern könntest über das Flag für jede Page individuell dynamisch zur Laufzeit festlegen, ob sie eine Kernel- oder Userspace-Page ist. Nur würde das die Verwaltung so kompliziert machen, dass man lieber in einem bestimmten virtuellen Adressbereich nur Kernelpages und in einem anderen Bereich nur Userpages hat, so dass man einer Adresse direkt ansieht, wohin sie gehört.

Zitat
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.
Genau, so geht es am besten. Wenn du verstanden hast, wie dieser Trick im Detail funktioniert, dann hast du das schwierigste am Paging geschafft.

Zitat
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?
Der Prozessor kennt immer nur ein einziges PD, nämlich das, auf das cr3 gerade zeigt. Für die PTs gilt das ähnlich, der Prozessor schaut nur diejenigen PTs an, auf die ein PTE im aktiven PD zeigt und nur, wenn auf die entsprechenden Adressen zugegriffen wird.

Abgesehen davon, dass du mit dem Prozessor einen zweiten Nutzer der Daten hast, sind es ganz normale Daten im RAM, die du allozierst und freigibst wie alles andere auch. Wenn du weißt, dass der Prozessor nicht mehr auf die Daten zugreift, kannst du sie auch für etwas ganz anderes wiederverwenden.

Zu den meisten Punkten habe ich nichts kommentiert. Wie bei einem guten Unix-Tool heißt das, dass das so passt. ;)
36
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 21. September 2016, 10:29 »
Also steht im 2. Byte von ebx immer noch eine 3 - sozusagen als Abfall.
Nicht ganz. ;)

Ein Byte hat 8 Bit, also zwei Hexziffern, nicht nur eine. 0x33 ist der Inhalt des ersten Bytes. Und das ist der ASCII-Code für das Zeichen '3', also passt genau.
37
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 20. September 2016, 10:46 »
Also der gepostete Code befüllt nicht ebx, sondern nur bl, falls das für deinen Kernel irgendeinen Unterschied machen sollte.

Hast du ebx denn mal als Hexzahl im Kernel ausgeben lassen?
38
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 12. September 2016, 19:27 »
qemu -d int zeigt mir die Kernel Register und gefühlt 1000 andere Dinge?
Es zeigt dir für den jeden Interrupt die Details zu diesem Interrupt an (also Vektor, Error Code, usw.) und zusätzlich einen CPU-Dump. Aus dem CPU-Dump interessiert dich im Moment wahrscheinlich eip, also die Adresse, an der gerade Code ausgeführt wurde als der Interrupt ausgelöst wurde.
39
Lowlevel-Coding / Re: Syscall wird nicht aufgerufen
« am: 12. September 2016, 12:12 »
Also wenn die int-Instruktion ausgeführt wird, passiert auf jeden Fall etwas. Falls dein IDT-Eintrag für Interrupt 0x30 nicht gültig wäre, würdest du zumindest einen GPF bekommen (oder wenn auch das nicht klappt, Double Fault oder Triple Fault). 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.

Zwischen zwei PIT-Interrupts müsste normal genug Zeit sein, um ordentlich Code ausführen zu können. 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.

Schau dir mal die Binärdatei an, ob der Compiler deine asm-Zeile nicht vielleicht sogar einfach weg"optimiert" hat. Wenn das das Problem ist, könnte ein asm volatile helfen.

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.
40
Softwareentwicklung / Re: GNU ld
« am: 10. September 2016, 10:00 »
DJGPP ist ja nichtmal ein Windows-Compiler, sondern ein DOS-Compiler, der meines Wissens schon immer (auch dem Ziel-OS geschuldet) ein paar Eigenheiten hatte. Ich persönlich würde den nicht für OS-Dev benutzen wollen. Nicht weil's nicht geht, sondern eher aus dem unbestimmten Gefühl heraus, dass da ständig irgendwas unerwartetes kaputt sein könnte, weil ein DOS-Compiler heutzutage sowieso wenig getestet wird und für sowas wie OS-Dev halt im Allgemeinen gar nicht benutzt wird.

Aber ich würde auch einen Haufen andere Sachen anders als Erhard machen, was sich auch darin ausdrückt, dass unsere Tutorialreihe auf Lowlevel etwas anders vorgeht.
Seiten: 1 [2] 3 4 ... 138

Einloggen