bootloader..
-
hallo..
bin grad etwas verwirrt und will deshalb fragen, wohin das bios jetz eigentlich den bootloader hinkopiert ? 00007C00 ? oder 7C000000 ?
in nem tut hab ich gelesen, dass man nich vorher weiss, in welchem offset
sich die startadresse des programs befindet. wie ist das zu verstehen ?die knallen da sowas vor dem eigentlichen code hin :
[ORG 0] jmp 07C0h:start ; Goto segment 07C0 start: ; Update the segment registers mov ax, cs mov ds, ax mov es, ax
kann ich mit tasm :
tasm32 boot.asm
tlink -t boot.objmeine com erstellen und die als bootloader nehmen ?
in meinem bootloader gibt er nur schrott aus anstatt den text.
(obwohl es unter windows fehlerfrei geht)
das riecht nach adressierungsprobleme ...mfg
-
[ORG 0x7c00] ;das heißt, das Programm befindet sich an Offset 0x7c00, wichtig für Addressierung innerhalb des Programms mov ax, cs mov ds, ax mov es, ax
Groß rumspringen brauchst du da nicht, das BIOS lädt deinen Code nach 0x0000:0x7c00 und führt ihn aus...
-
Steven schrieb:
Groß rumspringen brauchst du da nicht, das BIOS lädt deinen Code nach 0x0000:0x7c00 und führt ihn aus...
Schön wärs. MANCHE BIOSe starten die ausführung ab 0x0000:0x7c00. Manche aber auch ab 0x07c0:0x0000. (Es soll noch krankere Variationen geben, aber die sind wohl eher selten) Und dann gibts adressierungsprobleme. Mein erster Bootsektor ist höchstpersönlich an dem Problem verreckt
Deswegen macht man besser IMMER diesen kleinen Sprung am Anfang um für klare verhältnisse zu sorgen.
-
TriPhoenix schrieb:
Deswegen macht man besser IMMER diesen kleinen Sprung am Anfang um für klare verhältnisse zu sorgen.
Hm... Wozu?
IMHO ist der Sprung Unfug.
NEAR calls und jumps benutzen relative offsets, da ist es reichlich egal, ob der code nun beim offset 0000 oder 7C00 liegt; die Addresse und interne Addressierung des Kernels sollte einem ebenfalls bekannt sein...
Es reicht IMHO vollkommen, die Datensegmentregister statt mit cs, mit fixen werten zu setzen. (so machts MS auch)
Dazu speziell zu TASM .com-Dateien ein Beispiel:
IDEAL model tiny P386 codeseg org 100h Start: mov ax,07B0h ;07C0 -10h wegen org 100h bei .com-Dateien mov ds,ax mov es,ax mov ss,ax mov sp,0FFFEh cld mov si,offset Text call TextWr mov ax,0000h int 16h ;Auf Tastendruck warten mov dl,00h int 19h ;Bootsektor nochmal einlesen und ausfuehren Proc TextWr NEAR mov bx,0007h ;page 0/color mov ah,0Eh ;Write character in Teletype mode @@Loop: lodsb test al,al jz short @@Exit int 10h jmp short @@Loop @@Exit: ret Endp TextWr ;alle Daten muessen hier im selben Segmentblock liegen, sonst kommt die Datelaenge nicht hin Text db "Gratulation: Wenn du das lesen kannst, hast du den",0Ah,0Dh db "Datentraeger erfolgreich unbrauchbar gemacht! ;)",0Ah,0Dh,00h org 2FEh ;Datei 510(+org 100h) byte lang machen db 55h,0AAh ;Bootsektorzeichen end Start
-
Nobuo T schrieb:
TriPhoenix schrieb:
Deswegen macht man besser IMMER diesen kleinen Sprung am Anfang um für klare verhältnisse zu sorgen.
Hm... Wozu?
IMHO ist der Sprung Unfug.
NEAR calls und jumps benutzen relative offsets, da ist es reichlich egal, ob der code nun beim offset 0000 oder 7C00 liegt; die Addresse und interne Addressierung des Kernels sollte einem ebenfalls bekannt sein...
Es reicht IMHO vollkommen, die Datensegmentregister statt mit cs, mit fixen werten zu setzen. (so machts MS auch)
Das ist natürlich ne Argumentation...
ich mag trotzdem lieber genau wissen wo ich bin
-
hab gelesen, dass man auch eine dos exe basteln kann und dann einfach die ersten 512 bytes weglässt. das funktioniert scheinbar einwandfrei, speziell fuer tasm.
nur was ich immernoch net check: wenn ich mir ne dos exe bastel und nur ein segment hab (cs) und das ding wird jetz nach 0:7c00 kopiert oder nach 002:7c00 oder nach 07c0:0 oder
nach x:y und ich innerhalb von cs daten (text) anlege, warum muss ich mich dann überhaupt um die exakte speicherstelle kümmern ? wenn ich mir den offset von einem string innerhalb von cs hole, dass is doch dann ne relative adresse .. dürfte dem doch eigentlich nich jucken wo jetz der offset oder das segment liegt. der bootloader lädt das segment irgendwo hin, und innerhalb des segments kann ich doch tun was ich will oder ?
also ich versteh irgendwie nich die problematik die dahinter steckt...wäre fuer kurzen hinweis und erklärung nochmal dankbar
mfg
-
also scheinbar gehts nur dann, wenn ich cs, ds usw. auf 07c0 zeigen lasse..
(wie nobuo t im beispiel es gemacht hat, nur da musste man noch das org 100h berücksichtigen)
wenn ichs auf 0 mach gehts schon nichmehr..
also ich kann mir das nur so erklären, dass das bios scheinbar das ding
auf jeden fall auf 07c0:xxxx kopiert, anstatt auf 0:7c00warum steht dann überall dass der bootloader auf 0:7c00 kommt ?
dann hätte es mit ds=0, cs=0, ... gehen müssen...was ich auch seltsam finde, warum sich meine exe auf 31 kb aufbläht wenn ich org 07c00h schreibe...
mfg
-
Hammer schrieb:
also scheinbar gehts nur dann, wenn ich cs, ds usw. auf 07c0 zeigen lasse..
Wie an meinem Beispiel klargemacht, kannst du cs erstmal aus dem Spiel lassen, worauf das zeigt ist erstmal reichlich egal.
Mit welchem Wert ds befuellt werden muss, haengt nun davon ab, welches Startoffset dem Daten/Codesegment zugewiesen wurde. zB. muss ds bei org 100h auf 07B0h gesetzt werden.
Ich versuche diesen Zusammenhang einmal weiter auszufuehren...
Ich bleibe dabei jetzt erstmal bei einem Segment mit org 100h.Eine absolute Addresse in diesem Segment wird vom Assembler so berechnet, dass alle Bytes vom Anfang des Segments bis zu der durch (zB.) einen Variablennamen markierten Stelle gezaehlt werden und dazu nun der bei org angegebene Wert addiert wird.
Angenommen, der erste Buchstabe des Texts (markiert durch das Label "Text") in meinem Beispielprogramm, ist das 81h. Byte im Segment, dann ist die absolute Addresse, die der Assembler in alle OpCodes schreibt, die wie auch immer das Offset dieses Datums verwenden 81h + 100h (Wert von org) => 181h. Also wird zB. ausmov si,offset Text
letztendlich
mov si,0181h
erzeugt.
Da das BIOS unseren Bootsektor nun nach 00007C00h (physikalische Addresse) gepackt hat, liegt der erste Buckstabe des Textes nun bei 00007C00h + 81h => 00007C81h.
Nun kann man sich ueberlegen, welcher Segmentwert noetig ist, um aus einem Offset von 0181h die Physikalische Addresse 00007C81h anzusprechen.
Dazu folgende Formel zum Umrechnen einer RealMode Seg:Ofs-Addresse in eine phys. Addresse:physAddr=16*Seg+Ofs
Einmal umstellen, um den Wert fuer das Segment zu berechnen:
Seg=(physAddr-Ofs)/16Und Werte aus dem Beispiel eingesetzt:
Seg=(00007C81h - 0181h)/10h
=>Seg=07B0h
Ist zugegeben vielleicht ein bissel wirr erklaert, aber da steckt letztendlich wirklich nicht viel dahinter.
Hammer schrieb:
was ich auch seltsam finde, warum sich meine exe auf 31 kb aufbläht wenn ich org 07c00h schreibe...
Das ist AFAIK eine Eigenart von TASM: Das Segment wird von Offset 0 bis 7C00h mit 0-Bytes aufgefuellt.
Allgemein ist mir dieses Gebastel mit exe-Header abschnibbeln etc. ein wenig suspekt.
-
huhu.. THX!
jetz is alles klar..ich denke es bietet sich fuer einen bootloader ziemlich an eine com datei zu nehmen !
und das mit dem umrechnen gefällt mir. hab mir das system mit seg/offset nochmal klargemacht. ich habe erst die absolute adresse mit dem paragraphen-byte adresse verwechselt!aber für das programm, was vom bootloader ev. geladen werden soll, bietet sich eine dos-exe in meinen augen immernoch als besser an. man kann alle möglichkeiten einer exe voll ausnützen..
mfg
haMMer