Lowlevel
		Lowlevel => Lowlevel-Coding => Thema gestartet von: syxce am 24. January 2006, 21:40
		
			
			- 
				Hallo,
 ich versuche schon eine Weile das A20 Gate zu aktivieren aber ich erhalte immer von Bochs den Fehler: "PUSHAD: eSP < 16"
 Die Meldung das es erfolgreich aktiviert wurde wird jedoch ausgegeben.
 Was ist der Fehler ?
 danke
 
 ;A20 Gate aktivieren
 ;GDT laden
 ;Protected Mode schalten
 
 ;jmp 0x10000:0000
 
 
 enableA20:
 
 
 pusha
 
 ;; Make sure interrupts are disabled
 cli
 
 ;; Keep a counter so that we can make up to 5 attempts to turn
 ;; on A20 if necessary
 mov CX, 5
 
 .startAttempt1:
 ;; Wait for the controller to be ready for a command
 .commandWait1:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait1
 
 ;; Tell the controller we want to read the current status.
 ;; Send the command D0h: read output port.
 mov AL, 0D0h
 out 64h, AL
 
 ;; Wait for the controller to be ready with a byte of data
 .dataWait1:
 xor AX, AX
 in AL, 64h
 bt AX, 0
 jnc .dataWait1
 
 ;; Read the current port status from port 60h
 xor AX, AX
 in AL, 60h
 
 ;; Save the current value of (E)AX
 push AX			; 16-BIT
 ;; push EAX		; 32-BIT
 
 ;; Wait for the controller to be ready for a command
 .commandWait2:
 in AL, 64h
 bt AX, 1
 jc .commandWait2
 
 ;; Tell the controller we want to write the status byte again
 mov AL, 0D1h
 out 64h, AL
 
 ;; Wait for the controller to be ready for the data
 .commandWait3:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait3
 
 ;; Write the new value to port 60h.  Remember we saved the old
 ;; value on the stack
 pop AX			; 16-BIT
 ;; pop EAX		; 32-BIT
 
 ;; Turn on the A20 enable bit
 or AL, 00000010b
 out 60h, AL
 
 ;; Finally, we will attempt to read back the A20 status
 ;; to ensure it was enabled.
 
 ;; Wait for the controller to be ready for a command
 .commandWait4:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait4
 
 ;; Send the command D0h: read output port.
 mov AL, 0D0h
 out 64h, AL
 
 ;; Wait for the controller to be ready with a byte of data
 .dataWait2:
 xor AX, AX
 in AL, 64h
 bt AX, 0
 jnc .dataWait2
 
 ;; Read the current port status from port 60h
 xor AX, AX
 in AL, 60h
 
 ;; Is A20 enabled?
 bt AX, 1
 
 ;; Check the result.  If carry is on, A20 is on.
 jc .success
 
 ;; Should we retry the operation?  If the counter value in ECX
 ;; has not reached zero, we will retry
 loop .startAttempt1
 
 
 ;; Well, our initial attempt to set A20 has failed.  Now we will
 ;; try a backup method (which is supposedly not supported on many
 ;; chipsets, but which seems to be the only method that works on
 ;; other chipsets).
 
 
 ;; Keep a counter so that we can make up to 5 attempts to turn
 ;; on A20 if necessary
 mov CX, 5
 
 .startAttempt2:
 ;; Wait for the keyboard to be ready for another command
 .commandWait6:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait6
 
 ;; Tell the controller we want to turn on A20
 mov AL, 0DFh
 out 64h, AL
 
 ;; Again, we will attempt to read back the A20 status
 ;; to ensure it was enabled.
 
 ;; Wait for the controller to be ready for a command
 .commandWait7:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait7
 
 ;; Send the command D0h: read output port.
 mov AL, 0D0h
 out 64h, AL
 
 ;; Wait for the controller to be ready with a byte of data
 .dataWait3:
 xor AX, AX
 in AL, 64h
 bt AX, 0
 jnc .dataWait3
 
 ;; Read the current port status from port 60h
 xor AX, AX
 in AL, 60h
 
 ;; Is A20 enabled?
 bt AX, 1
 
 ;; Check the result.  If carry is on, A20 is on, but we might warn
 ;; that we had to use this alternate method
 jc .warn
 
 ;; Should we retry the operation?  If the counter value in ECX
 ;; has not reached zero, we will retry
 loop .startAttempt2
 
 
 ;; OK, we weren't able to set the A20 address line.  Do you want
 ;; to put an error message here?
 jmp .fail
 
 
 .warn:
 ;; Here you may or may not want to print a warning message about
 ;; the fact that we had to use the nonstandard alternate enabling
 ;; method
 
 .success:
 sti
 popa
 xor EAX, EAX
 mov si, msg_a20_ok
 call putstr
 ret
 
 .fail:
 sti
 popa
 mov EAX, -1
 mov si, msg_a20_fail
 call putstr
 ret
 
 
 msg_a20_ok db "A20 Gate aktiviert",13,10,0
 msg_a20_fail db "A20 Gate konnte nicht aktiviert werden",13,10,0
 
 putstr:
 lodsb
 or al, al
 jz short putstrd
 mov ah, 0x0E
 mov bx, 0x007
 int 0x10
 jmp putstr
 
 putstrd:
 retn
 
 
 
 times 512-($-$$) db 0
- 
				Hallo,
 das habe ich gemacht jedoch erhalte ich jetzt folgenden Fehler, zuerst der Code, dann ein Pic von Bochs.
 
 ;A20 Gate aktivieren
 ;GDT laden
 ;Protected Mode schalten
 
 ;jmp 0x10000:0000
 
 mov esp, 0x100
 
 enableA20:
 
 pusha
 
 ;; Make sure interrupts are disabled
 cli
 
 ;; Keep a counter so that we can make up to 5 attempts to turn
 ;; on A20 if necessary
 mov CX, 5
 
 .startAttempt1:
 ;; Wait for the controller to be ready for a command
 .commandWait1:
 xor AX, AX
 in AL, 64h
 bt AX, 1
 jc .commandWait1
 .
 .
 .
 .
 .
 
 
 (http://hittn.ssm-tec.at/fehler.JPG)
- 
				Du springs direkt auf die Punkte .fail und .succses
 jmp .success
 
 jmp .fail
 
 Versuchst dann aber mit einem RET zurückzukehren!
 
 .success:
 sti
 popa
 xor EAX, EAX
 mov si, msg_a20_ok
 call putstr
 ret
 
 .fail:
 sti
 popa
 mov EAX, -1
 mov si, msg_a20_fail
 call putstr
 ret
 
 Entweder du benutzt call um .fail und .success aufzurufen oder du machst nach ihrem Aufruf direkt weiter, anstelle ein ret einzusetzen!
 
 Kleiner TIP: Um das Programm kontrolliert zu stoppen benutzt man Endlosschleifen wie JMP $
 
 Und noch etwas, was bei bochs zwar keine Roll spielt aber bei echten PCs nötig ist: Am Ende eines Bootsektors gehört eine Bootsignatur, also anstelle von:times 512-($-$$) db 0
 
 das hier:times 510-($-$$) db 0
 dw 0xAA55
- 
				Ok danke, ich hab nun die "ret" mit einem jmp $ ersetzt und jetzt passts.
 Achja wegen der Bootsignatur, das ist nicht der Bootloader sondern einer der Kernel, trotzdem danke.