2011-01-04 10 views
17

Ich bin ein Teenager, der sich sehr für Assembler interessiert hat. Ich versuche, ein kleines Betriebssystem in Intel x86-Assembler zu schreiben, und ich frage mich, wie man direkt auf den Bildschirm schreiben, wie in ohne auf das BIOS oder andere Betriebssysteme angewiesen. Ich habe unter anderem die Quellen von Coreboot, Linux und Kolibri durchsucht, in der Hoffnung, einen Code zu finden und zu verstehen, der das tut. In dieser Hinsicht ist mir das noch nicht gelungen, obwohl ich glaube, dass ich mir den Linux-Quellcode noch einmal ansehen werde, da er mir die Quellen, die ich durchsucht habe, am verständlichsten ist.Wie kann ich direkt auf den Bildschirm schreiben?

Wenn jemand das weiß, oder weiß, wo in einem Stück Quellcode, den ich mir ansehen könnte, würde ich es schätzen, wenn sie mir erzählten.

Oder besser noch, wenn jemand weiß, wie man den I/O-Port auf einer Intel x86-CPU erkennt, der mit welchem ​​Teil der Hardware verbunden ist, wäre das auch zu schätzen. Der Grund, warum ich das fragen muss, ist, dass weder in dem Kapitel für die Ein-/Ausgabe im Intel 64 und IA-32 Architectures Softwareentwicklerhandbuch Band 1: Grundlegende Architektur, noch in den Abschnitten für die IN- oder OUT-Anweisung in Band 3, könnte ich eine dieser Informationen finden? Und weil es zu mühsam war, in den Quellen, die ich habe, nach den entsprechenden Anweisungen zu suchen.

+0

Wow, danke für die tollen Antworten, alle zusammen. Alle Antworten sehen so aus, als wären sie hilfreich. – user336462

+3

Haben Sie einen Sharpie in Betracht gezogen? Sie gleiten ziemlich leicht über die meisten CRT- und LED-Displays. –

Antwort

1

Ein wenig über meinen Rahmen hinaus, aber vielleicht möchten Sie in VESA suchen.

+0

Danke, dieser Ort sieht aus, als könnte es hilfreicher sein als die meisten Orte, die ich gesucht habe. – user336462

+0

@ user33662 Kein Problem. Lassen Sie uns wissen, wie es funktioniert und was Sie am Ende haben. –

+0

Ich bin mir nicht sicher, warum dies abgelehnt wurde, aber es wäre nett gewesen, eine Nachricht zu hinterlassen, warum. –

1

Für allgemeine I/O-Ports müssen Sie das BIOS durchlaufen, was Interrupts bedeutet. Vor vielen blauen Monden habe ich die Referenzen von Don Stoner benutzt, um beim Schreiben einiger Real-Mode-Assembly zu helfen, aber ich habe es nach ein paar Monaten ausgebrannt und das meiste von dem, was ich wusste, vergessen.

16

TEIL 1

Für alten VGA-Modi gibt es eine feste Adresse in den (legacy) Anzeigespeicherbereich zu schreiben. Für Textmodi beginnt dieser Bereich bei 0x000B8000. Für Grafikmodi beginnt es bei 0x000A0000.

Für hochauflösende Videomodi (z. B. über die VESA/VBE-Schnittstelle) funktioniert dies nicht, da die Größe des alten Anzeigespeicherbereichs auf 64 KiB begrenzt ist und die meisten hochauflösenden Videomodi viel mehr benötigen Leerzeichen (zB 1024 * 768 * 32-bpp = 2,25 MiB). Um das zu umgehen, gibt es 2 verschiedene Methoden, die von VBE unterstützt werden.

Die erste Methode heißt "bank switching", bei der nur ein Teil des Grafikspeichers der Grafikkarte in den alten Bereich abgebildet wird (und Sie können ändern, welcher Teil gemappt wird). Dies kann ziemlich unordentlich sein - zum Beispiel, um ein Pixel zu zeichnen, das Sie möglicherweise benötigen, um zu berechnen, in welcher Bank sich das Pixel befindet, dann zu dieser Bank wechseln und dann berechnen, welcher Offset in der Bank ist. Bei einigen Videomodi (z. B. 24-bpp-Videomodi mit 3 Bytes pro Pixel) befinden sich möglicherweise nur der erste Teil der Daten eines Pixels in einer Bank und der zweite Teil der Daten des gleichen Pixels in einer anderen Bank . Der Hauptvorteil davon ist, dass es mit Real-Mode-Adressierung arbeitet, da der Legacy-Display-Speicherbereich unter 0x00100000 liegt.

Die zweite Methode heißt "Linear Framebuffer" (oder nur "LFB"), wo der gesamte Bildschirmspeicher der Grafikkarte ohne lästige Bankumschaltung aufgerufen werden kann. Sie müssen die VESA/VBE-Schnittstelle fragen, wo sich dieser Bereich befindet (und er befindet sich normalerweise in der "PCI-Lücke" irgendwo zwischen 0xC0000000 und 0xFFF00000). Dies bedeutet, dass Sie im Real-Modus nicht darauf zugreifen können und den geschützten Modus oder den langen Modus oder den "unwirklichen Modus" verwenden müssen.

Um die Adresse eines Pixels zu finden, wenn Sie einen LFB-Modus verwenden, tun Sie etwas wie "pixel_address = display_memory_address + y * bytes_per_line + x * bytes_per_pixel". Die "bytes_per_line" stammt von der VESA/VBE-Schnittstelle (und ist möglicherweise nicht dasselbe wie "horizontal_resolution * bytes_per_line", da zwischen horizontalen Zeilen ein Padding möglich ist).

Für "Bank eingeschaltet" VBE/VESA-Modi wird es etwas mehr wie:

pixel_offset = y * bytes_per_line + x * bytes_per_pixel; 
bank_number = pixel_offset/bank_size; 
pixel_starting_address_within_bank = pixel_offset % bank_size; 

Für einige alte VGA-Modi (zB die 256-Farben "-Modus 0x13"), um es LFB sehr ähnlich ist, mit Ausnahme Es gibt kein Padding zwischen Zeilen und Sie können "pixel_address = display_memory_address + (y * horizontale_auflösung + x) * bytes_per_pixel". Für Textmodi ist es im Grunde dasselbe, außer 2 Bytes bestimmen jedes Zeichen und sein Attribut - z. "char_address = display_memory_address + (y * horizontale Auflösung + x) * 2". Für andere alte VGA-Modi (Monochrom-/2-Farben-, 4-Farben- und 16-Farben-Modi) ist der Speicher der Grafikkarte völlig anders angeordnet. Es ist in "Ebenen" aufgeteilt, wobei jede Ebene ein Bit des Pixels enthält, und (beispielsweise) um ein Pixel in einem 16-Farben-Modus zu aktualisieren, müssen Sie in vier separate Ebenen schreiben. Aus Leistungsgründen unterstützt die VGA-Hardware verschiedene Schreibmodi und verschiedene Lesemodi und es kann kompliziert werden (zu kompliziert, um es hier angemessen zu beschreiben).

TEIL 2

Für I/O-Ports (auf 80x86 "PC kompatible Geräte"), gibt es drei allgemeine Kategorien. Der erste ist ein De-facto-Standard-Legacy-Gerät, das feste I/O-Ports verwendet. Dazu gehören Dinge wie PIC-Chips, ISA-DMA-Controller, PS/2-Controller, PIT-Chip, serielle/parallele Ports usw. Fast alles, was beschreibt, wie jedes dieser Geräte programmiert wird, sagt Ihnen, welche I/O-Ports das Gerät verwendet.

Die nächste Kategorie sind Legacy-/ISA-Geräte, bei denen die von den Geräten verwendeten I/O-Ports durch Jumper auf der Karte selbst bestimmt werden und es keinen vernünftigen Weg gibt, die von ihnen verwendeten I/O-Ports zu bestimmen. Um dies zu umgehen, muss der Endbenutzer dem Betriebssystem mitteilen, welche E/A-Anschlüsse jedes Gerät verwendet. Glücklicherweise ist dieses krustige Zeug obsolet geworden (obwohl das nicht bedeutet, dass niemand es benutzt).

Die dritte Kategorie ist "plug & play", wo gibt es eine Methode, das Gerät zu fragen, welche I/O-Ports es verwendet (und in den meisten Fällen die I/O-Ports ändern, die das Gerät verwendet). Ein Beispiel hierfür ist PCI, wo es einen "PCI-Konfigurationsbereich" gibt, der Ihnen viele Informationen über jedes PCI-Gerät liefert. Bei diesen Kategorien kann niemand feststellen, welche Geräte die I/O-Ports zur Laufzeit verwenden, und wenn einige BIOS-Einstellungen geändert werden, können einige dieser Geräte die I/O-Ports ändern.

Beachten Sie auch, dass eine Intel-CPU nur eine CPU ist. Nichts verhindert, dass diese CPUs in etwas verwendet werden, das sich radikal von einem "PC-kompatiblen" Computer unterscheidet. Intels CPU-Handbücher werden niemals etwas über Hardware geben, die außerhalb der CPU selbst existiert (einschließlich des Chipsatzes oder der Geräte).

Teil 3

wahrscheinlich der beste Ort, um weitere Informationen zu gehen (das für OS-Entwickler/Bastler gedacht ist) sind http://osdev.org/ (ihre Wiki und ihre Foren).

+3

Ich würde hinzufügen, dass, außer wenn Sie eine GUI für Ihr Betriebssystem mit dem BIOS erstellen, es Zeit sparen wird, die Sie verbringen können "intrestring" Dinge wie Task-Switching und Speicherverwaltung. P.S. Ich denke jeder Teenager Programmierer sollte ein Betriebssystem schreiben;) auch wenn es nur ein Bootloader ist. Sie lernen so viel –

0

fand ich einen Ort, der in dieser Angelegenheit einige gute Informationen liefert: http://www.osdever.net/FreeVGA/home.htm Er spricht über einige Details wichtig, um Code zu schreiben, die direkt auf den Bildschirm schreibt. Ich fand es über den Link zu Don Stoners Website (Danke für den Link, SilverbackNet!). Ich bin immer noch auf der Suche nach mehr Informationen, also wenn jemand weitere Ideen hat, würde ich die Hilfe sehr schätzen.

1

Um direkt auf den Bildschirm schreiben, sollten Sie wahrscheinlich in den VGA-Textmodus Bereich schreiben. Dies ist ein Speicherblock, der ein Puffer für den Textmodus ist.

Der Textmodus-Bildschirm besteht aus 80x25 Zeichen; Jedes Zeichen ist 16 Bit breit. Wenn das erste Bit gesetzt ist, blinkt das Zeichen auf dem Bildschirm. Die nächsten 3 Bits geben dann die Hintergrundfarbe an; die letzten 4 Bits des ersten Bytes sind die Farbe des Vordergrunds (oder des Textzeichens). Die nächsten 8 Bits sind der Wert des Zeichens. Dies ist normalerweise Code-Seite 737 oder 437, aber es könnte von System zu System variieren.

Here ist eine Wikipedia-Seite dieser Puffer Detaillierung und here ist ein Link zu Codepage 437

Das BIOS in der Regel Dich in dem Textmodus setzt, aber wenn nicht, müssen Sie es selbst mit int10h (Modus 0x03)

eingestellt
+0

Blink Bit gilt nicht für alle Hardware/Emulatoren. Einige Hardware/Emulatoren blinken, während andere es als Intensitätsbit betrachten (1 = hohe Intensität, 0 = niedrige Intensität). Wenn Sie das erste Bit sagen, beziehen Sie sich auf das höchstwertige Bit (MSB). Normalerweise werden Bits von 0 bis n-1 nummeriert (wobei N in diesem Fall 16 ist). –

+0

Ja, wenn ich mich richtig erinnere, simuliert QEMU dieses Bit nicht, aber VirtualBox tut es. –

Verwandte Themen