Markus Wichmann
2006-09-07 16:02:50 UTC
Hi all,
ich bin gerade dabei, einen Bootloader für mein OS zu schreiben (alles
noch in der Mache). Der Bootloader hat ja die Aufgabe, die CPU in den PM
zu versetzen, um dann den Kernel zu rufen. Bis es soweit ist, muss ich
erstmal das A20 öffnen (wenn ich alles richtig verstanden habe). Das
wollte ich mit folgender Prozedur tun.
openA20:
cli ;disable interrupts
mov cx,5
startAttempt1:
call wkc ;gotta wait for keyb controller
mov al,0d0h ;ask for status byte
out 64h, al ;send request
call wkd ;wait for data part
xor eax,eax
in al,60h ;fetch status byte
push eax ;safe eax
call wkc ;begin to grow roots while waiting for keyboard
mov al,0d1h ;ask to set status byte
out 64h, al ;send request
call wkc ;roots grow longer...
pop eax
or al,10b ;set A20 byte
out 60h,al ;hope it will eat it
call wkc ;again the roots grow...
mov al,0d0h ;ask for status byte again (is A20 now open?)
out 64h,al
call wkd ;wait for data part
xor ax,ax
in al,60h
test al,10b ;please, A20 bit, PLEASE
jnz .success ;if so: Hooray!!
dec cx ;else: try this another 5 times
jnz startAttempt1
mov si,A20FailureMsg ;you got this far? well, write error message
call putstr
call halt ; halt system
.success
mov si,A20SuccessMsg ;now write success message
call putstr
sti ;bring back interrupts
ret
Die Prozedur wkc holt sich von Port 64h den aktuellen Status und wartet,
bis bei diesem das Bit 10b gesetzt ist. wkd macht das gleiche, bloß
guckt es nach dem Bit 1b.
Die Prozeduren putstr und halt sollten selbsterklärend sein. Die Ausgabe
läuft ja auch korrekt. Trotzdem läuft irgendetwas schief: Ich erhalte
immer meine Fehlernachricht. Das Protokoll von Bochs ist leider etwas
/zu/ umfangreich: Ich kann mich nicht durchfitzen. Ob was dazu
drinsteht, weiß ich auch nicht. Ich habe einfach mal 32-Bit-Code
angeordnet. Ist doch OK, oder? Ausgeführt wird der Code ja.
Nehmt also einfach an, der Code würde auf einer Diskette im Bootsektor
laufen. Das ich einen x86 habe, brauche ich wohl nicht zu erwähnen ;-).
Mein Keyboard ist ein kabelloses am PS/2-Anschluss. Ist da A20 schon von
Anfang an offen/gar nicht berücksichtigt?
Und bevor ihr fragt: A20SuccessMsg und A20FailureMsg sind lediglich
sz-Variablen (ja sz. Dafür habe ich gesorgt.) Und putstr erwartet die
Basisaddresse des Strings in SI. (Ich überlege noch, ob ich nicht doch
auf Pascal-Strings umstelle, da mit C ja schon einmal ein OS geschrieben
wurde, mit Pascal hingegen noch nicht.)
Doch ich schweife ab, und davon geht A20 auch bloß nicht auf.
Was mache ich falsch?
Btw habe ich den obigen Code von
http://www.osdever.net/tutorials/a20.php?the_id=4 genommen und so
abgewandelt, dass ich immer die Prozeduren aufrufe, nicht in neu
erstellte Schleifen reingehe. (ist nicht so clever, immer den gleichen
Code selbst zu tippen, wenn es doch einmal Anspringen auch tut.)
tia und cya,
nullplan
ich bin gerade dabei, einen Bootloader für mein OS zu schreiben (alles
noch in der Mache). Der Bootloader hat ja die Aufgabe, die CPU in den PM
zu versetzen, um dann den Kernel zu rufen. Bis es soweit ist, muss ich
erstmal das A20 öffnen (wenn ich alles richtig verstanden habe). Das
wollte ich mit folgender Prozedur tun.
openA20:
cli ;disable interrupts
mov cx,5
startAttempt1:
call wkc ;gotta wait for keyb controller
mov al,0d0h ;ask for status byte
out 64h, al ;send request
call wkd ;wait for data part
xor eax,eax
in al,60h ;fetch status byte
push eax ;safe eax
call wkc ;begin to grow roots while waiting for keyboard
mov al,0d1h ;ask to set status byte
out 64h, al ;send request
call wkc ;roots grow longer...
pop eax
or al,10b ;set A20 byte
out 60h,al ;hope it will eat it
call wkc ;again the roots grow...
mov al,0d0h ;ask for status byte again (is A20 now open?)
out 64h,al
call wkd ;wait for data part
xor ax,ax
in al,60h
test al,10b ;please, A20 bit, PLEASE
jnz .success ;if so: Hooray!!
dec cx ;else: try this another 5 times
jnz startAttempt1
mov si,A20FailureMsg ;you got this far? well, write error message
call putstr
call halt ; halt system
.success
mov si,A20SuccessMsg ;now write success message
call putstr
sti ;bring back interrupts
ret
Die Prozedur wkc holt sich von Port 64h den aktuellen Status und wartet,
bis bei diesem das Bit 10b gesetzt ist. wkd macht das gleiche, bloß
guckt es nach dem Bit 1b.
Die Prozeduren putstr und halt sollten selbsterklärend sein. Die Ausgabe
läuft ja auch korrekt. Trotzdem läuft irgendetwas schief: Ich erhalte
immer meine Fehlernachricht. Das Protokoll von Bochs ist leider etwas
/zu/ umfangreich: Ich kann mich nicht durchfitzen. Ob was dazu
drinsteht, weiß ich auch nicht. Ich habe einfach mal 32-Bit-Code
angeordnet. Ist doch OK, oder? Ausgeführt wird der Code ja.
Nehmt also einfach an, der Code würde auf einer Diskette im Bootsektor
laufen. Das ich einen x86 habe, brauche ich wohl nicht zu erwähnen ;-).
Mein Keyboard ist ein kabelloses am PS/2-Anschluss. Ist da A20 schon von
Anfang an offen/gar nicht berücksichtigt?
Und bevor ihr fragt: A20SuccessMsg und A20FailureMsg sind lediglich
sz-Variablen (ja sz. Dafür habe ich gesorgt.) Und putstr erwartet die
Basisaddresse des Strings in SI. (Ich überlege noch, ob ich nicht doch
auf Pascal-Strings umstelle, da mit C ja schon einmal ein OS geschrieben
wurde, mit Pascal hingegen noch nicht.)
Doch ich schweife ab, und davon geht A20 auch bloß nicht auf.
Was mache ich falsch?
Btw habe ich den obigen Code von
http://www.osdever.net/tutorials/a20.php?the_id=4 genommen und so
abgewandelt, dass ich immer die Prozeduren aufrufe, nicht in neu
erstellte Schleifen reingehe. (ist nicht so clever, immer den gleichen
Code selbst zu tippen, wenn es doch einmal Anspringen auch tut.)
tia und cya,
nullplan
--
To err is human. To forgive is divine.
To forget is also human...
To err is human. To forgive is divine.
To forget is also human...