Autor Thema: Bootloader - Code  (Gelesen 6997 mal)

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« am: 29. June 2004, 08:56 »
hi, (schon wieder der... z z z z )

ich habe mir mal den source von stormos gedownloaded und versuche nun ihn zu verstehen.

mov ax,cs
 mov ds,ax
 mov es,ax
 mov gs,ax
 mov fs,ax
was genau macht man hier.
ich habe mir da überlegt das segmente als code segmente deklariert werden,...
oder so...

mov ax,0x7B0
 mov ss,ax
 mov sp,0xF0
dann das?! warum fängt der stack-pointer bei 0xF0 an?! bei mir war das immer 0.

noch ne andere frage:
was ist der unterschied zwischen
mov si, [msg]
und
mov si, msg
und
mov si, offset msg
??
ich glaube [msg] und offset msg ist das gleiche, oder??
need dringend help ;P

chr15

  • Beiträge: 279
    • Profil anzeigen
    • http://www.clinux.de.vu
Gespeichert
« Antwort #1 am: 29. June 2004, 13:39 »
Da oben werden einfach nur die Stacksegmente initialisiert. Das in CS stehende Segment ist das einzigste Segment das genutzt wird und es enthält sowohl Code als auch Daten.
Das mit demn Stack ist so, da er von oben nach unten wächst. Darum wird die Startadresse auch möglichst weit nach oben gesetzt.

[msg] gibt den Speicher an der Adresse an
msg dürfe den Inhalt der Varibel msg angeben (eventuell das gleiche)
offset msg gibt den Offset der Msg an, also die Adresse und nicht den Wert an der Adressse

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #2 am: 29. June 2004, 14:19 »
[msg] = der Wert, der an der Adresse gespeichert wird
msg = Adresse auf den Wert
offset msg = msg

so glaub ich, dass es gehört...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #3 am: 29. June 2004, 14:57 »
ok vielen dank.

aber wenn der stack nach unten wächst, dan habe ich mit

mov sp,0xF0
gar kein platz darauf, oder?

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #4 am: 29. June 2004, 16:18 »
ja, wenn der stack aber (so wie es ist) nach oben wächst haste ne menge platz ;-)
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

chr15

  • Beiträge: 279
    • Profil anzeigen
    • http://www.clinux.de.vu
Gespeichert
« Antwort #5 am: 29. June 2004, 16:39 »
Bei 8086 und kompatiblem wächst der Stack nach unten. Das wird doch auch in der Lowlevelausgabe 1 Beschrieben und auch im Assembler Tut, dass TeeJay leider (soweit ich weiß) immer noch nicht veröffentlicht hat.

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #6 am: 29. June 2004, 16:41 »
Zitat
chr15 postete
Das mit demn Stack ist so, da er von oben nach unten wächst. Darum wird die Startadresse auch möglichst weit nach oben gesetzt.
na was nun?? oben nach unten (9,7,6,5,4...) oder unten nach oben (0,1,2...)?

ihr verwirrt mich ;)

habe ich nun so mehr platz
mov ax,0x7B0
 mov ss,ax
 mov sp,0xF0
als so
mov ax,0x7B0
 mov ss,ax
 mov sp,0
??

chr15

  • Beiträge: 279
    • Profil anzeigen
    • http://www.clinux.de.vu
Gespeichert
« Antwort #7 am: 29. June 2004, 16:52 »
Der Beweis: Aus Lowlevel Ausgabe 1:

Zitat
Als Besonderheit des Stacks ist zu beachten, dass die Adresse der
aktuellen Stackspitze von oben nach unten wächst, d. h. je mehr Elemente
auf den Stack gelegt werden, desto niedriger ist die Adresse der
Stackspitze.
Das mit deinen Beispielen ist so: im 2. Beispiel hast du 0 Bytes, im ersten zweihunderdundnochwas Bytes Platz. Es kann natürlich sein, das du auch im 2. Fall was puschen kannst. Dann wird der Stachpointer durch einen Überlauf (Oder UNterlauf eher gesagt) auf 0xFFFF gesetzt, wenn du ein Byte Pusht.

joachim_neu

  • Beiträge: 1 228
    • Profil anzeigen
    • http://www.joachim-neu.de
Gespeichert
« Antwort #8 am: 29. June 2004, 19:50 »
sorry, hab mich detäuscht, kommt warscheinlich daher, dass in beispielen der stack immer mit einem tellerstapel verglichen wird, der ja nach oben wächst... sorry...
http://www.joachim-neu.de | http://www.orbitalpirates.de | http://www.middleageworld.de

System: 256 RAM, GeForce 2 MX 400, AMD Athlon XP 1600+, Windows XP, 1x Diskette, 1x DVD-ROM, 1x CD-R(W) Brenner,...

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #9 am: 30. June 2004, 08:13 »
ok thx!

was ist genau der Unterschid zwischen:
org 0
start:
 jmp 0x7C0:weiter
weiter:
und

org 0x7c0
??

und what is dat?
mov bx,0x7C0
 mov es,bx
sorry wegen den vielen fragen. aber habe keinen schimmer was hier abgeht o,O

thx4help [zacK][<<<]

stultus

  • Beiträge: 486
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 30. June 2004, 17:19 »
1) startaddresse = 0, beim sprung wird aber zum offset der funktion noch ein 0x7C0 addiert.
2) setzt startaddresse auf 0x7c0,
3) ist vermutlich eine andere variante fürn ORG Befehl
MSN: planetconquestdm@hotmail.de
ICQ: 190-084-185

... Wayne?

chr15

  • Beiträge: 279
    • Profil anzeigen
    • http://www.clinux.de.vu
Gespeichert
« Antwort #11 am: 30. June 2004, 17:24 »
Ich schätze mal, das es nicht kompatibel ist, da beim setzen der Startadressen auch die Adressen der Variablen um 0x7C0 verschoben werden. So dürftest du bei dem Obigen Beispiel keine VAriablen benutzen, die im Programm stehen und auch das benutzen von absoluten Sprüngen würde zu Fehlern führen.

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #12 am: 30. June 2004, 23:42 »
hm
der bootloader funktioniert aber, mitsamt variablen.

testet sonst mal: www.stormos.net

mfg

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #13 am: 01. July 2004, 00:00 »
Das ist wie folgt.

Beim laden des Bootsektors wird dieser in den Speicher an die Adresse 0x7c0 kopiert und ausgeführt. Zu diesem Zeitpunkt "zeigen" alle Segemtregister auf das Segment 0.

Wenn nun in dem Assemblerquelltext auf eine Variable verwiesen wird, errechnet der Assembler beim kompilieren die Anzahl Bytes die die Variable vom Anfang des Codes entfernt ist und fügt diese "Adresse" fest in den Code ein. Wenn nun der Bootloader startet und auf eine Variable verwiesen wird die sich (mal angenommen) 10 Bytes vom Anfang des Codes entfernt befindet, dann wird der Code so kompiliert, das er versucht von der Adresse 10 (also Offset 10) die Variable zu lesen. Da die Segmentregister aber auf das Segment 0 zeigen (anfang des Speichers) wird der Code versuchen am Offset 10 (0000:000A) die Variable zu lesen. Das wird aber scheitern, da der Bootloadercode ja erst bei 0000:07C0 beginnt.

Das org 0x7c0 macht nichts anderes, als den Assembler darauf hinzuweisen, das er zu den errechneten Adressen der Variablen den Wert 0x7C0 hinzuzuaddieren.

Somit wird im Speicher auf die korrekte Speicherstelle zugegriffen.

Eine andere Möglichkeit ist es, das CS-Register mit dem Wert 0x7C0 zu füllen. Somit wird das Offset der Variable ab dem Segment 0x7C0 gesucht. Nun stimmen die Offseterrechnungen des Assemblers wieder, da der Code nun beim Offset 0 im Segment 0x7C0 beginnt.

Hier wurde im Code mit einem Far-Jump das CS-Register mit dem Wert 0x7C0 geladen.

Beide varianten führen zum selben Erfolg. Welche man wählt ist also eigentlich vollkommen egal.
----------------------
Redakteur bei LowLevel

GhostCoder

  • Beiträge: 187
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 01. July 2004, 09:36 »
Hiho,

soweit ich weiß, wird der Bootsektor an due Adresse (nicht segment:offset) 0x7C00 kopiert. und auf dieses Addresse kann man nun mit 0x07C0:offset zugreifen, da, addresse=(segment << 4)+offset was in diesem Falle 0x7C00+offset ergeben würde. Außerdem sind nicht alle Segmente null. cs kann von BIOS zu BIOS unterschiedlich sein. Meistens ist es 0x07C0, aber darauf kann man sich nicht verlassen, daher ist es am besten, alle anderen Segmente auf 0x07C0 zu setzen.

@TeeJay
Welchen Wert das cs Register hat ist vollkommen egal, da das Standard Segment prefix (fast) immer ds ist. Daher muss man bei seinem Bootcode einfach nur ds-gs auf 0x07C0 zusetzen, und man kann auf seine Variablen zugreifen.

Ich mache es immer so:
;mov ax,cs ;nur zum testen unter win
mov ax,0x07C0
mov ds,ax
mov es,ax

MfG GhostCoder
A man, a legend!

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #15 am: 01. July 2004, 10:33 »
Ja ja das stimmt. Es war schon spät nachts als ich das geschrieben habe.

Es ging mir ja auch nur darum das man versteht wozu org dient und warum man es auch anderes machen kann.

GS und FS kann man im Bootloader aber getrost außen vorlassen, da die Register erst im PMode verwendung finden.
----------------------
Redakteur bei LowLevel

zacK

  • Beiträge: 216
    • Profil anzeigen
    • http://www.domae.ch
Gespeichert
« Antwort #16 am: 01. July 2004, 16:48 »
ok, thx vielmal.

wie muss ich genau forgehen bei einem bootloader??

ist das richtig:

1. Fat-Tabelle in RAM laden [9 Sektoren]
2. Nach kernel suchen in den Fat-Tabellen
3. ..... (nun  weiss ich nicht mehr weiter)

und noch ne frage
-> ist es komplizierter wenn die datei in einem subdir ist?

ich hätte drum folgende struktur geplant:

a:
apps
    -> app.x
krnl
    -> kernel.sys (zu ladende datei)
    -> loader.sys (auch laden)
profile
    -> root
          -> profile.cfg
usr
     ->home

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #17 am: 01. July 2004, 18:03 »
das wird schon komplizierter.
Das root dir bietet sich an, da es bei FAt12 direkt hintereinander auf der Diskette steht.

EIn Subdir kann bereits auf der Diskette verstreut sein, was die Sache umfangreicher macht.


Nach dem Kernel sucht man nicht in der FAT-Tabelle, sondern im Rootdir.
Wenn du den Eintrag gefunden hast, dann musst du dort auslesen in welchem Sector der Kernel beginnt.
Dann liest du diesen Sektor in den RAM.
Dann schaust du in der FAT-Tabelle nach dem Eintrag und kannst dort sehen ob du noch einen weiteren Sektor lesen musst, oder ob der Kernel vollständig geladen ist.
----------------------
Redakteur bei LowLevel

 

Einloggen