Ich muss für ein Betriebssystem codieren, auf dem ich einen Rechner ausführen kann. Es ist wie ein Desktop-Rechner. Dazu lese ich die brokenthorn operating development series Ich habe die second stage of bootloader abgeschlossen Der Bootloader ist im Real-Modus. Danach erklärt der Autor den geschützten Modus. Ich möchte den geschützten Modus nicht verwenden. Dafür habe ich keine Zeit. Also möchte ich den Rechner im Real-Modus schreiben, indem ich Bios Interrupts benutze. Ist es möglich? Ich denke, es kann auf der zweiten Stufe des Bootloaders geschrieben werden (ich bin mir nicht sicher.) Also ich brauche keinen Kernel (ich bin mir nicht sicher). Ich weiß nicht, wie man BIOS Interrupts verwendet, um mit der Tastatur umzugehen. Kann mir jemand einen Link zur Verfügung stellen, der mir dabei hilft? Und wenn etwas falsch in was ich oben angenommen falsch ist, bitte korrigieren Sie mich. Vielen Dank im Voraus.Wie behandelt man Tastatur im Real-Modus durch BIOS-Interrupts?
Antwort
Wenn Sie High-Level-BIOS-Tastatur-Dienste verwenden möchten, statt sich mit der Tastatur selbst zu unterbrechen, dann ist INT 16h
was Sie wollen.
INT 16h
mit AH=00h
oder 10h
wird auf einen Tastendruck blockieren warten (liefert ASCII Ergebnis in AL
); Verwenden Sie AH=01h
oder 11h
, um anzufragen, ob ein Tastendruck zuerst verfügbar ist, wenn Sie das Blockieren vermeiden möchten (kehrt sofort mit ZF
zurück, wenn ein Schlüssel verfügbar ist, oder setzen Sie, falls nicht). Siehe z.B. here oder here (oder Google "INT 16h" für mehr).
Verzeihung, guter Herr - jede Idee, wie man "Umgang mit der Tastatur unterbricht sich selbst" ohne den High-Level-Bios-Service?Was sind die Nachteile bei der Nutzung solcher High-Level-Dienste? Ist die Leistung schlechter? – travisjayday
Sie können IRQ 1 (vom x86-Controller auf Interrupt 9 gemappt) verarbeiten und die Schlüssel von Port 60h
lesen.
Siehe http://inglorion.net/documents/tutorials/x86ostut/keyboard/.
-1. Es ist nicht IRQ 9, es ist IRQ 1: http://www.webopedia.com/quick_ref/IRQnumbers.asp. IRQ 9 ist für generische andere Geräte wie PCI-Geräte verfügbar. IRQ1 ist der Tastatur-Interrupt. – Matt
@Matt, aus dem Link in meiner Antwort: 'Der Tastatur-Controller verwendet IRQ 1. Der x86-Interrupt-Controller mappt dies auf Interrupt 9, so erhalten eine IRQ von der Tastatur-Controller hat die gleiche Wirkung wie die Ausführung von Int 9. ' –
Wenn die PIC wird nicht neu zugeordnet und Sie verwenden kein IOAPIC, es ist dasselbe wie das Ausführen von INTERRUPT 9 (das mit der Ausnahme NPX_OVERRUN CPU und nicht mit dem Handler IRQ9 überlappt). Obwohl die Zuordnung zwischen IRQs und Interrupts konfigurierbar ist, ist IRQ9 nie == IRQ1. In der Tat, von Ihrem eigenen Link: 'Der Tastatur-Controller verwendet IRQ 1'. Da alle Betriebssysteme das PIC so neu zuordnen, dass IRQs CPU-Ausnahmen nicht überlappen, wäre es besser zu sagen, dass die Tastatur IRQ1 verwendet. – Matt
Minimal Gas Bootsektor BIOS Beispiel:
.code16
.global _start
_start:
cli
/* Set SS and SP as they may get used by BIOS calls. */
xor %ax, %ax
mov %ax, %ss
mov 0x0000, %sp
/* Get input to %al */
mov $0x00, %ah
int $0x16
/* Print the input from %al */
mov $0x0E, %ah
int $0x10
hlt
.org 510
.word 0xaa55
kompilieren und ausführen:
as -o main.o main.S
ld --oformat binary -o main.img -Ttext 0x7C00 main.o
qemu-system-i386 -hda main.img
Oder einfach klonen this repository und make run RUN=bios_keyboard
laufen.
Wenn Sie dann ein Zeichen eingeben, wird es auf den Bildschirm gedruckt.
Getestet auf Ubuntu 14.04 AMD64, Binutils 2.24, QEMU 2.0.0 und auf echter Hardware Lenovo Thinkpad T400.
Mögliches Problem mit Ihrem Code ist, dass Sie davon ausgehen, dass Sie ein gültiges Stapelsegment (SS) und Stapelzeiger (SP) haben. BIOS-Interrupts benötigen Stack-Speicherplatz, so dass es ratsam ist, vor dem BIOS-Aufruf ein gültiges 'SS' und ein' SP' einzurichten. Sie können sich nicht wirklich auf den Status von Segmentregistern verlassen, wenn das BIOS zu Ihrem vom Boot-Sektor geladenen Code springt. Die emulierten und VM-Umgebungen sind oft in der Lage, Dinge in einem gültigen Zustand zu belassen, aber auf echter Hardware ist das nicht immer der Fall. –
@MichaelPick danke für die Info! Ich werde es mir ansehen. Worauf sollte ich sie einstellen? Für 'SP' ist jeder Speicher hoch über 0x7C00 in Ordnung, oder gibt es einen besseren spezifischen Wert? 'SS' zu 0 nehme ich an. –
Alles, was brauchbar ist, ist in Ordnung, aber ich bleibe in der Regel von etwas weniger als 0x0000: 0x1000 und darunter. Sie könnten das Stack-Segment knapp unter 0x0000: 0x7C00 setzen (was ich in der Vergangenheit normalerweise getan habe) –
Sie werden [PC Interrupts] [1] als ein unschätzbares Werkzeug finden. Sie können es unter dem Link für <$ 4.00 erhalten. [1]: http://www.amazon.com/PC-Interrupts-Programmer-Reference-Third-Party/dp/0201624850 – Tergiver