Autor Thema: Stack funktioniert nicht / funktioniert schon?  (Gelesen 6010 mal)

babyrabbit

  • Beiträge: 5
    • Profil anzeigen
    • Baby Rabbit Music
Gespeichert
« am: 03. June 2011, 02:52 »
Hallo!

Ich hab mich jetzt auch hier registriert, da ich mich ernsthaft mit der Entwicklung eines OS beschäftigen will.
Tutorials hab ich schon ein paar durchgearbeitet und verstehe in etwa die grundlegenden Dinge, die für die Programmierung eines Bootloaders erforderlich sind.

Also der grundsätzliche Ablauf in meinem Fall:

Stage1: (Bootsektor)
  • ok: Stack einrichten
  • fail: verschiedene Meldungen ausgeben
  • ok: Stage2 von Floppy laden (liegt roh im 2. Sektor, ist noch nicht größer als 512 Bytes)
  • ok: zu Stage2 springen

Stage2:
  • versch. Meldungen ausgeben
  • in den Protected Mode schalten (kommt erst später)

Während Stage1 abgearbeitet wird erscheint keine Meldung auf dem Schirm - ab Stage2 arbeitet die Ausgabefunktion / der Stack korrekt so wie es sein soll. :?

*edit:
Tools: NASM und Bochs 2.4.6
Auch in Boch 2.4.5 war das Problem bereits sowie auf einem alten P4-System mit Floppy-Laufwerk.




Der Stage1-Loader:
[BITS 16]
ORG 07C0h
JMP stage1.start

%include "bpb.asi"
%include "io.asi"

stage1:
;Festlegen des Stacks und Initialisierung der Register
.start:
MOV AX, 07C0h
ADD AX, 544
CLI
MOV SS, AX
MOV SP, 0x1000
MOV BP, SP
STI
XOR AX, AX
MOV DS, AX
MOV ES, AX
MOV [boot_drv], DL

.main:
CALL setVideomode
f_print boot_msg, 0x0007

f_print fd_reset, 0x0009
.reset:
MOV AH, 00h
MOV DL, [boot_drv]
INT 13h
JC .reset
f_print boot_ok, 0x000A

f_print fd_read, 0x0009
.read:
MOV AX, 0x100
MOV ES, AX
XOR BX, BX

MOV AH, 02h
MOV AL, 1
MOV CH, 0
MOV CL, 2
MOV DH, 0
MOV DL, [boot_drv]
INT 0x13
CMP AL, 0
JC .read

.end:
f_print boot_ok, 0x000A
JMP 0x100:0

boot_drv DB 0
boot_msg DB "booting stage1...",13,10,0
boot_ok  DB "OK",13,10,0
boot_ko  DB "FAIL",13,10,0
fd_reset DB 9,"Drive reset:",9,0
fd_read  DB 9,"Drive read: ",9,0
TIMES 510-($-$$) DB 0
DB 0x55
DB 0xAA

Die Ausgabefunktion wird von Stage1 und Stage2 verwendet:
%macro f_print 2
PUSH word %2 ;color
MOV SI, %1 ;string
CALL print
ADD SP, 2
%endmacro

print:
PUSH BP ; -> alten BASE-POINTER sichern
MOV BP, SP ; -> BASE-POINTER auf den aktuellen STACK-POINTER setzen

MOV AH, 0Eh
.next:
LODSB
OR AL, AL
JZ .end
MOV BX, [SS:BP+4] ; Zugriff auf 1. Parameter
INT 10h
JMP .next
.end:
MOV SP, BP ; <- alten STACK-POINTER wiederherstellen (siehe oben: BP = alter SP)
POP BP ; <- alten BASE-POINTER wiederherstellen
RET

aus Stage2:
[BITS 16]
ORG 0x1000
JMP stage2.start

%include "io.asi"
%include "gdt.asi"

stage2:
.start:
f_print boots2_msg, 0x000F
CLI
HLT



Anmerkung: Ich verwende die Endung *.asi für "ASsembler Include". :wink:
"bpb.asi" enthält den BIOS-Parameter-Block


Ich hab schon unzählige Versuche unternommen, das Stacksegment und den -Pointer anders zu initialisieren, doch es bleibt immer wieder der selbe "Fehler".
Es scheint so, als ob in BX durch MOV BX, [SS:BP+4] nichts reingeschrieben werden kann bzw. aus irgendeinem Grund der Wert im Register immer 0x0 ist / wird / bleibt.
==> Nur der Text booting stage2... (in Weiß) wird ausgegeben


Hat von euch jemand einen Lösungsvorschlag für das Problem?


Greets
« Letzte Änderung: 03. June 2011, 06:36 von babyrabbit »
Wer die Dynamik nicht ehrt ist die Loudness nicht wert!

PNoob

  • Beiträge: 106
    • Profil anzeigen
    • Mein Blog
Gespeichert
« Antwort #1 am: 03. June 2011, 07:32 »
Moin

Du nutzt ja ein Macro um die Parameter auf den Stack zu pushen, wenn ich das richtig verstehe ist der erste Parameter derSstring und der zweite die Farbe.
f_print fd_read, 0x0009
Im stage2 nutzt du bei dem Text der ausgegeben wird 0x000F eventuell liegts daran das du nur den Text sehen kannst?


Einen eigenen Bootloader programmmieren ist, wie du in diesem diesem Thread hier lesen kannst ziemlicher Mist und ich, wie sehr wahrscheinlich gleich auch noch mehrere andere, rate dir dazu Grub zu benutzen.

PNoob

babyrabbit

  • Beiträge: 5
    • Profil anzeigen
    • Baby Rabbit Music
Gespeichert
« Antwort #2 am: 03. June 2011, 09:30 »
Moin ^^

Wenn ich keinen Stack verwende und die Farbwerte manuell nach BX vor dem Call schreibe funktionierts und es ist schön bunt.
Sobald die Parameter aber über den Stack gehen setzt es in der Stage1 aus.

Du nutzt ja ein Macro um die Parameter auf den Stack zu pushen, wenn ich das richtig verstehe ist der erste Parameter derSstring und der zweite die Farbe.
f_print fd_read, 0x0009
Im stage2 nutzt du bei dem Text der ausgegeben wird 0x000F eventuell liegts daran das du nur den Text sehen kannst?
Ja, mit einem Makro - richtig. Das find ich persönlich besser vom Handling, weil man nur 1x den korrekten Funktionsaufruf inkl. Stack-Operationen programmieren muss.
Mit der Farbe hat das aber nichts zu tun, sonst würde der Text von der Stage2 nicht ganz links oben erscheinen.


Folgendes kann ich als Fehlerquelle definitiv ausschließen:
  • Parameter String(adresse) bzw. Farbe
  • Unterprogramm "setVideomode"

Ich hab mir schon überlegt, ob es nicht sein kann, dass nach dem Initialisieren des Stacks irgendwas geflusht werden muss, damit es auch übernommen wird (ähnlich wie beim far jump zum P-Mode Code? <- wenn ich das richtig verstanden hab)
Gibts da irgendwelche Befehle?


DEBUG-STUFF
rax: 0x00000000:00000e00 rcx: 0x00000000:00000000
rdx: 0x00000000:00000000 rbx: 0x00000000:00000000
rsp: 0x00000000:00000ff4 rbp: 0x00000000:00000ffa
rsi: 0x00000000:000e08ad rdi: 0x00000000:0000ffac
r8 : 0x00000000:00000000 r9 : 0x00000000:00000000
r10: 0x00000000:00000000 r11: 0x00000000:00000000
r12: 0x00000000:00000000 r13: 0x00000000:00000000
r14: 0x00000000:00000000 r15: 0x00000000:00000000
rip: 0x00000000:00007c58
eflags 0x00000046: id vip vif ac vm rf nt IOPL=0 of df if tf sf ZF af PF cf


Stack address size 2
 | STACK 0xadf4 [0x0ff6] TEST: aktueller SP gepusht
 | STACK 0xadf6 [0x09e0] TEST: SS gepusht
 | STACK 0xadf8 [0x0ffa] TEST: neuer BP (= alter SP) gepusht
 | STACK 0xadfa [0x1000] alter BP / 1. Zeile im Unterprogramm
 | STACK 0xadfc [0x7c85] BP+2 > Rücksprung
 | STACK 0xadfe [0x0007] BP+4 > Param1: Lightgray
 | STACK 0xae00 [0x0000] >>> ANFANG <<<

-------------------------------------------------------------------------------------------
__TESTWERTE__
SS:SP = 0xadf6 > SP=0x0ff4 OK. (SUB SP 2) kommt erst nach dem PUSH (siehe RSP)
SS:BP = 0xadfa OK.
SS:SP_alt = 0xadfa OK.
SS:BP_alt = 0xae00 OK.
-------------------------------------------------------------------------------------------

Der Stack ist also auch nicht das Problem, wenn die Werte korrekt draufliegen.

... ich, wie sehr wahrscheinlich gleich auch noch mehrere andere, rate dir dazu Grub zu benutzen.
von GRUB bin ich keinesfalls abgeneigt :)
ich möchte nur mal schauen, wei weit ich selber komme - zwecks Verständnis undso ;)

Greets
Wer die Dynamik nicht ehrt ist die Loudness nicht wert!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 03. June 2011, 10:13 »
der Boot Sektor wird nach 0x7C00 geladen. Wie die adresse auf segment:offset aufgeteilt wird ist meines wissens nach nicht ganz eindeutig geregelt. (0x0000:0x7C00, oder 0x07C0:0x0000),

deine ORG 0x07C0 passt auf keines von beiden.

da du ds=0 verwendest würde ich dir empfehlen:

ORG 0x7C00

start:
jmp 0x0000:.setCS_IP  ;um cs:ip auf 0x0000:(0x7C00+x) zu setzen
.setCS_IP

und so nebein bei, wenn du sowas, der lesbarkeit halber aufteilen willst:
MOV AX, 07C0h
ADD AX, 544
dann ist
MOV AX, 07C0h + 544die bessere wahl.

« Letzte Änderung: 03. June 2011, 10:19 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

babyrabbit

  • Beiträge: 5
    • Profil anzeigen
    • Baby Rabbit Music
Gespeichert
« Antwort #4 am: 03. June 2011, 11:18 »
deine ORG 0x07C0 passt auf keines von beiden.

Wow herzlichen Dank!!
Und wieder so ein "einfacher" Fehler, der Wochen lang nicht entdeckt wurde  :roll: :-D

Hab das jetzt so abgeändert:
ORG 0x7C00
JMP 0x0000:stage1.start ; CS:IP -> 0x0000:(0x7C00+x)

%include "bpb.asi"
%include "io.asi"

stage1:
;Festlegen des Stacks und Initialisierung der Register
.start:
MOV AX, 07C0h + 544
CLI
MOV SS, AX
MOV SP, 0x1000
MOV BP, SP
STI

Ist die 2. Zeile praktisch gesehen dann eh das was du meintest mit dem setCS_IP?
Es haut jetzt so jedenfalls hin.

Und auch ein Danke für den Lesbarkeits-Tipp!

Wahrscheinlich weil ich mit den vom Assembler berechneten Adressen im Bereich 0x0500 - 0x7BFF (unused) war, kamen nur Nullen (ASCII 0x00).
Wer die Dynamik nicht ehrt ist die Loudness nicht wert!

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 03. June 2011, 11:25 »
Ich würde den Pfeil im kommentar der 2. Zeile zwar andersrum drehen, aber ja das macht genau das was ich gemeint habe.
« Letzte Änderung: 03. June 2011, 11:35 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen