2015-12-17 11 views
5

Obwohl es wunderbar komplette Boot-Loader zur Verfügung stehen, habe ich in meiner Freizeit ein und aus als eine pädagogische Übung geschrieben. Ich bin auf ein Problem gestoßen.Vorbereiten, einen Kernel zu laden

Ich bin in der Lage, eine erste Boot-und Kettenladung andere Sektoren ohne Problem durchzuführen. Wenn ich mein eigenes Betriebssystem schreiben würde, wäre ich gut zu gehen. :) Stattdessen versuche ich Linux zu bootstrappen. Die Herausforderung, die ich habe, ist zweifach.

  1. Ich verstehe, dass I need to load the kernel (Linux) into memory at 0x100000. Ich weiß, dass ich die "HdrS" Signatur bei Offset 0x202 des Kernels finden sollte. Ich weiß auch, dass die Startadresse in 0x214 sein sollte. Wenn ich jedoch zu der Adresse an diesem Ort springe, hält es an. Offensichtlich ist es ziemlich schwierig, einen Debugger darum herum zu wickeln. :) Fehle ich etwas in dieser Kette von Fakten, um die richtige Startadresse des Kernels zu bestimmen?
  2. Ich vermute, dass die Antwort auf (1) etwas damit zu tun haben könnte, etwas Speicherbereich mit Hardware-Discovery-Informationen zu füllen. Ich habe mehrere passierende Verweise auf diese auf gesehen, aber ich scheine zu fehlen, wo dies ist und genau welche Daten da sein müssen. Ist der Bootloader für die Hardwareerkennung verantwortlich? Wenn ja, welche Daten müssen wo hingelegt werden?

Ein weiterer Punkt zur Kenntnis zu nehmen ist, dass ich bereits in 32-Bit-Protected-Mode, weil ich mit der Erstellung eines EFI-Boot-System zu tun habe, so 16-Bit-Real-Modus ist hier nicht wirklich eine Option, die Beseitigung der Real-Mode-Startort im Kernel.

+0

Es ist trivial einen Debugger um this_ zu _wrap ... nur eine virtuelle Maschine. Hell, Linux kommt sogar mit Quellcode;) – Jester

+0

Willst du auf Bare-Metal debuggen? Versuchen Sie es mit einem anderen Maschinensimulator. Das hat den Vorteil, dass das Pausieren zu Einzelschritten völlig transparent sein kann, weil die Uhr (und Timer-Interrupts usw.) stoppt. –

+0

@PeterCordes Ja. Ich erinnere mich, dass Bochs auch eine Debug-Verbindungsschnittstelle hat, oder? Ich werde sehen, ob das hilft, aber alle es mir wirklich zeigen würde, ist, dass ich erfolgreich an die Stelle von 0x214 angezeigt Springen bin ... Ich vermute, dass ich entweder immer meine Adresse aus der falschen Stelle oder # 2 oben ist mein Problem. –

Antwort

2

@Jester hat mein Problem gefunden und beide Fragen beantwortet. Die Lösung war eigentlich in der file that I had linked, obwohl ich den entsprechenden Abschnitt verpasst hatte. Ich bin auch das entsprechende Stück hier für die Nachwelt:

In 32-Bit-Boot-Protokoll, wobei der erste Schritt einen Linux-Kernel sollte die Boot-Parameter (struct boot_params zu eingerichtet werden, in Laden, traditionell bekannt als „Null Seite"). Der Speicher für die Struktur boot_params sollte allen null zugewiesen und initialisiert werden. Dann sollte der Setup-Header vom Offset 0x01f1 des Kernel-Image auf in die Struktur boot_params geladen und untersucht werden. Das Ende des Setup-Header kann als folgt berechnet werden:

0x0202 + Byte-Wert bei 0x0201 Offset

Neben dem Setup-Header der Struktur boot_params wie die 16-Bit-Boote zu lesen/ändern/schreiben Protokoll, sollte der Bootloader auch die zusätzlichen Felder der Struktur boot_params als in zero-page.txt beschriebenen füllen.

Nach dem Einrichten der Struktur boot_params kann der Bootloader den 32/64-Bit-Kernel auf die gleiche Weise wie das 16-Bit-Bootprotokoll laden.

Im 32-Bit-Boot-Protokoll wird der Kernel gestartet, indem zum 32-Bit-Kernel-Einstiegspunkt gesprungen wird. Dies ist die Startadresse des geladenen 32/64-Bit-Kernels.

Bei Eintrag muss die CPU mit Paging Behinderten in 32-Bit-Modus geschützt sein; ein GDT muß mit den Deskriptoren für Selektoren __BOOT_CS (0x10) und __BOOT_DS (0x18) geladen werden; beide Deskriptoren müssen 4G flach sein; __BOOT_CS muss über die Berechtigung zum Ausführen/Lesen verfügen, und __BOOT_DS muss Lese-/Schreibberechtigung haben; CS muss __BOOT_CS sein und DS, ES, SS muss __BOOT_DS sein; Interrupt muss deaktiviert sein; % esi muss die Basisadresse der Struktur boot_params; % ebp,% edi und% ebx müssen null sein.

64-Bit-Anweisungen können auch in diesem Dokument gefunden werden.