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).
Wow, danke für die tollen Antworten, alle zusammen. Alle Antworten sehen so aus, als wären sie hilfreich. – user336462
Haben Sie einen Sharpie in Betracht gezogen? Sie gleiten ziemlich leicht über die meisten CRT- und LED-Displays. –