Autor Thema: Bootloader  (Gelesen 20919 mal)

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« am: 29. February 2004, 22:26 »
Alloa.
Da ich selbst hin und wieder ein bisschen am OS-Coden bin, hab ich mir mal einen Bootloader geschrieben um mir das ausprobieren etwas komfortabler zu machen. Mir war es lästig jedes mal mit RawWrite auf eine Diskette schreiben zu müsen. Daher hab ich einen Bootloader geschrieben der eine binäre Datei aus dem Root-Verzeichnis einer FAT12 formatierten Diskette in den Speicher läd und dann ausführt.

Da hier leider noch keine Funktion vorhanden is um bequem Code zu posten, stelle ich diesen auf meiner HP zum DL bereit.

http://www.sub--zero.de/scripts/htmlgenerator.php?page=bootloader&directory=tutorials

Ganz am Ende ist der Link zur Zip mit dem Code.
----------------------
Redakteur bei LowLevel

bscreator

  • Gast
Gespeichert
« Antwort #1 am: 29. February 2004, 23:05 »
Hallo Leute,
ich bin gerade dabei, dem Benutzer das Eingeben von Zeichen zu erlauben.
Das Auswerten einzelner Zeichen ist einfach, ob Return-Taste oder andere Sonderzeichen (F1-F12,Pos1,Einfg,...) gedrückt wurden, funktioniert einwandfrei. Lediglich habe ich Probleme, eine ganze, vom Benutzer eingegebene Zeichenkette auszuwerten. Meine Idee war, ein Byte-Array anzulegen, das alle eingegebenen Zeichen speichert. Mit der Return-Taste wird der ganze Text zu einem String zusammengesetzt. Bis jetzt konnte mir jedoch keiner sagen, wie man ein Array in NASM erstellt, noch wie man auf das erstellte Array zugreift und die einzelnen Inhalte der Elemente auswertet. Langer Rede kurzer Sinn: Wie erstellt und greift man auf ein Byte-Array in NASM zu?
Habt vielen Dank Leute, Tschüss.

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #2 am: 29. February 2004, 23:32 »
Variable resb 100

So erstellst du ein Array das 100 bytes lang ist.
Das erste Byte wird über das Offset "Variable" adressiert.
Alle weitere Bytes adressierst du mit einem Displacement.
Sprich Variable+1, Variable+2

Ich hatte mal eine Art Shell programmiert.
Da hab ich es so gemacht, das ich ein 100 Byte langes Array hatte.
Wenn eine taste gedrückt wird, wird das Zeichen in das Array geschrieben.
Wenn nun Return gedrückt wurde, so wird ein NULL-Byte hinter das letzte eingegebene Zeichen geschrieben.
So kannst du dann die Eingabezeile als String ansprechen.
Du musst natürlich überprüfen das nicht mehr als 99 Zeichen eingegeben werden, weil du ja noch Platz für das NULL-Byte brauchst.

Auch musst du berücksichtigen das man mit Backspace ein Zeichen löschen kann.
----------------------
Redakteur bei LowLevel

bscreator

  • Gast
Gespeichert
« Antwort #3 am: 01. March 2004, 09:22 »
Hallo TeeJay,
Ich habe Deinen Plan beherzigt und mal ein bischen rumgespielt. Mit den Arrays hab´ ich seltsamerweise nur unter NASM Schwierigkeiten. Die Meldung
"warning: uninitialised space declared in .text section: zeroing". Mein derzeitiger Bootcode:
[BITS 16]
ORG 0x7C00

start:
mov si,InfoScreen
call SetString
call GetAndSet

GetAndSet:
mov AH,0x10
int 0x16
cmp AL,0x0d   ;Vergleich, ob Enter-Taste gedrückt wurde...
je Return        ;Wenn gleich, springe zu Return
mov AH,0x0E   ;Taste Return nicht betätigt
mov BL,0x07
int 0x10
jmp GetAndSet

InfoScreen db 'TestOS, Version 1.0',13,10,0
Array resb 100

Return:
ret

times 512-($-$$)-2 db 0
dw 0AA55h

Das ist mein derzeitiger Tastaturcode. Die Abfragen für die Sondertasten hab´ ich mal weggelassen. Das Deklarieren der Strings, sprich InfoScreen, Booting,... funktioniert in diesem Teil des Codes wunderbar. Nur das Deklarieren des Arrays funktioniert in diesem Abschnitt des Codes nicht (obige Fehlermeldung).

Was mach ich falsch?
Danke, bscreator

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #4 am: 01. March 2004, 15:25 »
Das ist nur eine Warnung und kein Fehler.
Das besagt nur das du ein Array erstellst, dessen Werte nicht initalisiert sind.
Das macht aber nix, da du das Array ja erst zur Laufzeit mit Buchstaben füllst und DANN erst benutzt.

Du kannst auch folgedendes machen:

Variable db "                       "

Sprich du erstellst einen String der mit lauter Leerzeichen gefüllt ist.
Damit hast du dann keine Fehlermeldung mehr. Jedoch ist es schwer zu erkennen wie groß dein Array ist.

Die Warnung kannst du also ignorieren. Ist nur ein Hinweis das du dich nicht fälschlicher weise darauf verlässt das den Array zu Beginn schon sinnvolle Daten enthält.
----------------------
Redakteur bei LowLevel

Lizer

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 01. March 2004, 15:25 »
Wie die Warnung besagt, hast du den Array nicht initialisiert, weshalb der Assembler in nullt, also die einzelnen Bytes mit 0 initialisiert. Probiers doch mal statt dessen mit:

Array: times 100 db 0x00

Sollte den gleichen Effekt haben.

Lizer

  • Beiträge: 28
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 01. March 2004, 15:27 »
Ui, TeeJay war schneller...

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #7 am: 01. March 2004, 16:05 »
Japp :D

Du könntest auch schreiben:
Variable db 0
times 100 db 0

So hättest du ein 101 Byte großes Array das am Offeset Variable beginnt.

Damit hättest du wohl auch keine Warnung mehr und du könntest also auch sehen wie groß das Array ist.
----------------------
Redakteur bei LowLevel

mastermesh

  • Beiträge: 341
    • Profil anzeigen
    • http://www.kostenloser-laptop.de/
Gespeichert
« Antwort #8 am: 01. March 2004, 17:13 »
Ja, der Loader scheint nützlich zu sein. Zusammen mit MTools und Bochs das ultimative Werkzeug zum Testen von OSes ;)

bscreator

  • Gast
Gespeichert
« Antwort #9 am: 01. March 2004, 18:02 »
Lizer, TeeJay und mastermash - habt Dank.

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 01. March 2004, 18:19 »
Also ich hab mal grad auf die Site des Loaders geklickt und das überflogen... das sind ja mindestens unendlich seiten TEXT !!!

ich weiss das der loader fat12 lädt
so aber die anderen Features kenn ich leider nicht...

ist das nur ein standart loader oder kann er auch protected mode und so

vielleicht kannst du ja ein bisl mehr dazu schreiben, ob es sich für mich lohnt den endloslangen text .. oder den source durchzuarbeiten :)

würde mich freuen

bscreator

  • Gast
Gespeichert
« Antwort #11 am: 01. March 2004, 19:00 »
Hi Leute, ich bins nochmal,
Jetzt versuch´ ich gerade, auf das Array zuzugreifen. Meine erste Idee
war die Syntax von C, in NASM: mov Array[9],9 (Sollte in das neunte Element des Arrays "Array" den Wert 9 speichern. Allerdings bin ich mit der Idee ganz schön auf die Nase geflogen. Ich hab´ zig klammern gesetzt, mit der Hoffnung im Hintergrund, durch Zufall auf die richtige Lösung zu kommen. Als ich jetzt mal deine Shell betrachtet hab´, hab´ ich ganz aufgegeben. Könnt ihr mir erklären, welche Register ich wie verwenden muss, um z.B. in ein Byte-Array mit 100 Elementen, in das 4. Element den Wert 9 zu schreiben? Und wie man dann auch wieder auf diesen Wert zugreift?

Dafür wäre ich euch wirklich sehr dankbar.
Tschüss

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #12 am: 01. March 2004, 19:51 »
Zum Bootloader.


Dieser enthält nur die Minimalfunktionen um:
- Die FAT-Tabelle in den Speicher zu laden.
- Einträge aus der FAT-Tabelle zu lesen
- Das Root-Directory nach einer Datei zu durchsuchen
- Die Datei komplett in den Speicher zu lesen
- Die Datei auszuführen (Sprich an die Speicherstelle zu springen an welche die Datei geladen wurde).

Da ich mich auf die 512 Bytes begrenzt habe, blieb kein Platz mehr um in den PMode zu schalten.
Ich halte es auch nicht für Sinnvoll, da jeder ja seine eigen GDT für sein OS einrichten möchte/sollte. Und daher wäre es wohl blöd das im Bootloader vorwegzunehmen.


Sobald ich aber damit fertig bin, werde ich Code und Zusatztools mit denen man "bequem" in den PMode schalten kann im Resource-Center posten.
----------------------
Redakteur bei LowLevel

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #13 am: 01. March 2004, 19:57 »
@bscreator

Das mit den Arrays kannst du so machen:

So erstellst du ein 100 byte langes Array dessen Startoffset "Test" ist:
Variable  db 0
times 99 db 0

Wenn du nun auf das Array zugreifen willst, dann machst du das wie folgt:

So schreibst du in das erste Element eine 9:
mov       [Variable  ],  BYTE 9

So schreibst du in das 6te Element eine 10:
mov       [Variable+5], BYTE 10

geschnallt?
----------------------
Redakteur bei LowLevel

bscreator

  • Gast
Gespeichert
« Antwort #14 am: 01. March 2004, 21:39 »
Funktioniert einwandfrei - vielen Dank, TeeJay

neq

  • Beiträge: 44
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 01. March 2004, 22:32 »
ja wäre cool wenn du so ne zusatzfunktion machen würdest.

bscreator

  • Gast
Gespeichert
« Antwort #16 am: 02. March 2004, 11:03 »
Hi Leute,
Bevor ich das Array in mein Betriebssystem einbette, hab ich zuerst einmal ein bischen geübt. Um ein Array zu testen hab´ ich mal ein kleines Programm geschrieben:

[BITS 16]

jmp start

ORG 0x0

start:

Eingabe db 0
times 255 db 0 ;reserviert ein Array mit 255 Elementen, jedes mit 0 initialisiert
Counter db 0    ;Array-Zähler
Msg db 'Array Ende erreicht',13,10,0

call GetAndSet

GetAndSet:
mov AH,0x10   ;Videomodus setzen
int 0x16      ;Interrupt
cmp AL,0x0d   ;Vergleich, ob Enter-Taste gedrückt wurde
je Return        
xchg [Counter],eax ;Speichere ASCII-Wert von Taste in Counter
mov [Eingabe+eax], byte AL  ;Array aktualisieren
inc eax         ;Array-Zähler erhöhen
cmp eax,10   ;11 Einträge? (0 bis 10 = 11 Elemente)
je ArrayEnde ;Wenn eax Wert 10, dann Meldung ausgeben
xchg [Counter],eax ;Array-Zähler nach Counter
je Return    
mov AH,0x0E   ;Taste ist nicht Enter-Taste...
mov BL,0x07
int 0x10
jmp GetAndSet

SetString:
lodsb              ;Byte laden
or al,al
jz Return
mov ah,0x0E        ;Funktion 0x0E
mov bx,0x0007      ;Attribut-Byte (wird nicht ben”tigt)
int 0x10           ;schreiben
jmp SetString      ;Nächstes Byte

ArrayEnde:
mov si,Msg  
call SetString ;Meldung ausgeben
call Return

Return:
ret

Ich weiss, das Programm ist unterste Schublade, aber zum Testen des
Arrays reichts. Da ich nicht gerade viel Ahnung davon hab´, wie man Zahlen in Variablen speichert, hab ich es, mehr oder weniger, mit dem eax-Register und dem xchg-Befehl versucht. Wenn 10 Einträge gemacht worden sind (255 Zeichen einzugeben, um das Array zu testen war mir zuviel) sollte eigentlich die Meldung ausgegeben werden "Array Ende erreicht". Das Programm wird allerdings nur normal beendet. Wo liegt der Fehler ?

TeeJay

  • Beiträge: 630
    • Profil anzeigen
    • http://www.jay-code.de
Gespeichert
« Antwort #17 am: 02. March 2004, 14:37 »
Zahlen in Variablen speichern:

mov [Variable], BYTE 10
anstatt BYTE kannst du auch WORD oder DWORD nehmen.
Das kommt halt darauf an wie groß deine Variable ist.

mov [Variable], al
geht auch. Hier brauchst du nicht extra angeben ob es sich um ein BYTE/WORD oder DWORD handelt, da es aus der Angabe des Registers ersichtlich ist.

Du arbeitest ja wie oben angegeben im 16-BIT Mode.
Daher solltest du auch möglichst nur 16-BIT Register (AX,BX, CX usw) verwenden.
Du benutzt häufig eax. Das ist zwar möglich, jedoch ist das dann teilweise 32-Bit. Mal abgesehen das du eine größe von 32-BIT an Zahl garnicht benötigst, da weder dein Array noch die Werte darin größer als 65535 sind.

xchg [Counter], eax
das sollte zu chaos führen, weil du hier einen 32-Bit Wert vom Register in eine BYTE Variable speichern willst (Counter db 0).

mov [Eingabe+eax], byte al
Du machst hier einen gedankenfehler. Du benutzt eax um ein Feld im Array anzugeben und gleichzeitig willst du mit einem Teil von eax, nämlich al einen Wert in das Array schreiben. Das kann eigentlich nur zu blödsinn führen ;)

Daher bricht auch deine Schleife nie ab. Weil du in AL immer eine Taste einlädst. Und da wird eher per Zufall die Zahl 10 in eax stehen.
Du solltest also für das ansprechen der einzelnen Felder im Array lieber bx benutzen.

PS: Nimms nicht als Beleidigung, aber du solltest dich vielleicht in Sachen Assembler noch etwas schlau machen bevor es ans OS-Coding gibt.
Dein Code zeigt das du noch starke schwächen hast. Ich würde dir empfehlen ein Buch zu kaufen. Ich selbst habe mir mal das Buch "Programmiersprache Assembler - Eine strukturierte Einführung" von "Reiner Becker" gekauft.
Das ist zwar mehr ein Taschenbuch (also nicht sehr dick) und in erster Linie auf DOS ausgeichtet. Jedoch fand ich es für den Einstieg ganz gut, weil dort auch grundlegende Sachen über Assembler zu lesen waren. Sprich wie man mit SI und DI Strings bearbeitet usw.

Ansonsten könnte ich dir anbieten ein eBook zu schicken. Das ist zwar in Englisch und auch auf DOS ausgelegt, jedoch umfasst es 1000 Seiten und da steht wirklich alles drin.
----------------------
Redakteur bei LowLevel

bscreator

  • Gast
Gespeichert
« Antwort #18 am: 02. March 2004, 19:49 »
Bücher hab´ ich schon genug. Das von Dir angesprochene Buch hab´ ich auch, allerdings find ich es halt blöd, dass diese ganzen Programme in den Büchern die MASM oder TASM-Syntax verwenden. Diese beiden Assembler brauchen WINDOWS oder DOS als Betriebssystem, wodurch meine erstellten Programme plattformabhängig, sprich WINDOWS oder DOS, werden. Weil die Syntax der beiden jedoch kaum der von NASM ähnelt, zumindest was ich bisher verglichen habe, kann ich die Bücher für NASM-Programmieren wohl fast vergessen. Zugegeben, die Bücher beinhalten auch eine Menge Wissen, was Rechnerarchitektur beinhaltet. Diese Kapitel hab´ ich allerdings nur überflogen - sollte wohl mal genauer nachsehen. Wenn ich Bücher über den NASM-Assembler kennen würde, hätt ich die längst gekauft. Daher denke ich, da sowieso die meisten Betriebssysteme mit dem NASM-Assembler geschrieben sind (habe ich zumindest gehört), dass ich gleich NASM verwenden sollte.
Da Du, dem Buch zufolge, mit MASM angefangen hast, und soviel Wissen über NASM hast, sollte ich das vielleicht auch machen, oder?
PS: Wäre nett, wenn Du mir so ein EBook schicken würdest.
Danke nochmal und machs gut!

bscreator

  • Gast
Gespeichert
« Antwort #19 am: 02. March 2004, 21:54 »
Wenn Du mit MASM angefangen hast (Die Codes des Buches sind, soviel ich gehört habe, mit diesem Assembler geschrieben), sollte ich das vielleicht auch tun.
Ich hab´ nen 32-Bit-Macro Assembler (MASM) gefunden. Was ist der Unterschied zwischen nem "normalen" Assembler und einem Macro-Assembler?
Tschüss.

PS: MASM32 Version 8 [32Bit Macro Assembler] zum Download (2,98 MB) bei:
     http://www.codingcrew.de/masm32/index.php

 

Einloggen