1 Punkte von GN⁺ 2024-07-16 | 1 Kommentare | Auf WhatsApp teilen
  • Menschen unterscheiden zwischen Dingen, die komplex sind, und Dingen, die einfach nur kompliziert sind. Komplexität gilt als interessant, Kompliziertheit jedoch als schädlich. Der Einrichtungsprozess einer x86_64-CPU ist größtenteils Letzteres.
  • Es wird erklärt, wie man die CPU von einem durch das BIOS geladenen Bootsektor aus vom 16-Bit-Real-Mode in den 64-Bit-Long-Mode versetzt. Diese Einrichtung ist grundlegend, und es ist noch weitere Arbeit erforderlich.
  • Benötigt werden das Intel 64 and IA-32 Architectures Software Developer’s Manual, ein Assembler (verwendet wird nasm) und QEMU. Kenntnisse in x86-Assembly und der nasm-Syntax sind erforderlich.

Ausgangspunkt: BIOS

  • Nach dem Reset befindet sich eine x86-CPU im "Real Mode". Dieser Modus hat standardmäßig eine 16-Bit-Operandengröße. Mit Segmentierung kann 1 MB Speicher adressiert werden.
  • Der erste nach dem BIOS ausgeführte Code befindet sich im Bootsektor. Das BIOS sucht im System nach dem ersten Sektor, der mit 0xaa55 endet, und lädt diesen Bootsektor an die Speicheradresse 0x7c00.
  • Das BIOS stellt 512 Byte bereit, mit denen der Rest des Bootloaders per Bootstrap geladen werden muss.

Bootsektor einrichten

  • Es wird ein einfacher Bootsektor eingerichtet, der mithilfe von BIOS-Routinen eine Nachricht auf dem Bildschirm ausgibt und dann anhält. So lässt sich prüfen, ob die Werkzeuge funktionieren.
  • Der Bootsektor wird mit Assembly-Code und einem Makefile eingerichtet.

Schritt 1 – Stufe 2 von der Festplatte laden

  • Der Bootloader kann in zwei Stufen aufgeteilt werden. Stufe 1 ist der Code im Bootsektor, also alles, was das BIOS lädt. Der einzige Zweck von Stufe 1 ist es, Stufe 2 in den Speicher zu laden.
  • In Stufe 2 wird vom 16-Bit-Real-Mode in den 32-Bit-Protected-Mode gewechselt. Im Protected Mode können keine BIOS-Routinen mehr verwendet werden. Das Laden von Sektoren von der Festplatte wird deutlich komplizierter.
  • Es wird erklärt, wie man über das BIOS auf die Festplatte zugreift.

32-Bit-Protected-Mode

  • Die CPU wird vom Real Mode (16 Bit) in den Protected Mode (32 Bit) versetzt. Im Protected Mode wird Segmentierung verwendet, um Speicherschutz zu implementieren.
  • Bevor in den Protected Mode gewechselt wird, muss eine Global Descriptor Table (GDT) definiert werden. Die GDT wird als zusammenhängende Struktur im Speicher definiert.
  • Es wird erklärt, wie man die GDT definiert und in den Protected Mode wechselt.

64-Bit-Long-Mode

  • Bevor in den Long Mode gewechselt werden kann, muss sich die CPU im Protected Mode befinden und Paging aktiviert sein. Der Protected Mode ist bereits eingerichtet, aber Paging wird noch benötigt.
  • Paging ersetzt die Segmentierung zur Verwaltung des virtuellen Adressraums, von Berechtigungen und mehr. Es wird erklärt, wie man Seitentabellen für den Wechsel in den Long Mode erstellt.
  • Es wird erklärt, wie man eine GDT für den Long Mode definiert und vom Protected Mode in den Long Mode wechselt.

Zusammenfassung von GN⁺

  • Dieser Artikel erklärt detailliert den Prozess, eine x86_64-CPU vom 16-Bit-Real-Mode in den 64-Bit-Long-Mode zu versetzen. Dadurch lässt sich das Verständnis für die Entwicklung von Bootloadern und Betriebssystem-Kernels vertiefen.
  • Er behandelt verschiedene Konzepte wie BIOS, Bootsektor, Protected Mode und Long Mode und liefert für jeden Schritt den nötigen Assembly-Code sowie die Konfiguration.
  • Der Artikel ist nützlich für Menschen, die sich für Betriebssystementwicklung interessieren, und vermittelt insbesondere ein tiefes Verständnis der x86-Architektur. Ein Projekt mit ähnlicher Funktionalität ist "Writing a Simple Operating System – from Scratch".

1 Kommentare

 
GN⁺ 2024-07-16
Hacker-News-Kommentare
  • Es gibt eine Möglichkeit, in den Long Mode zu wechseln, ohne direkt in den Protected Mode umzuschalten
    • Es wurde ein Bootloader erstellt, der einen kleinen 64-Bit-Kernel in den Bootsektor lädt
    • Enthalten ist auch der Vorgang, den Kernel von der Festplatte zu laden und den VESA-Modus einzurichten
  • Der 80286 hatte das 16-Bit-Register MSW, und der 80386 erweiterte dieses zu CR0 mit 32 Bit
    • Der 64-Bit-Long-Mode fügte das EFER-MSR hinzu und erweiterte CR0 auf 64 Bit
    • Derzeit werden nur 11 Bits von CR0 und 8 Bits von EFER verwendet
    • Ich frage mich, warum Intel/AMD nicht die freien Bits in den bestehenden Registern verwendet haben
  • Der am unnötigsten komplexe Teil dieses Artikels sind das Makefile und das Linker-Skript
    • NASM kann Flat-Binary-Ausgaben erzeugen, aber offenbar hält man deren Nutzung für zu sehr einen „Hack“
  • Alle Schritte, die nötig sind, um die CPU in den richtigen Modus zu versetzen, sind unnötig komplex
    • Offenbar sind all diese Schritte für die Abwärtskompatibilität erforderlich
    • Intel hätte von Anfang an ein Flag oder einen Befehl bereitstellen können, um im richtigen Modus zu starten
    • Oder man hätte sämtliche Abwärtskompatibilität entfernen können
    • Ich meine mich zu erinnern, einmal untersucht zu haben, ob ARM64 ein ähnliches Problem hat
    • Ich frage mich, ob es CPUs gibt, die von Anfang an als 64-Bit-CPUs entworfen wurden
    • Das Ziel/Design von Itanium dürfte wohl in diese Richtung gegangen sein
  • Es könnte UEFI-Befürworter geben, die nicht verstehen, warum ein neuer Bootloader-Ansatz entwickelt wurde
    • Wie der Autor sagt: „Wenn du bis hierhin gekommen bist, ist das schon ziemlich cool“
  • Ich frage mich, wie alt UEFI inzwischen ist
    • Schade, dass BIOS nicht zusammen mit dem Long Mode abgeschafft wurde
  • Ich frage mich, ob dieser Boot-Prozess mit EFI/UEFI kompatibel ist
    • Ich frage mich, ob ein UEFI-Supervisor auf echter Hardware Real Mode, Protected Mode und Long Mode tatsächlich emuliert
  • Ich frage mich, ob dieser Prozess auf ARM einfacher ist