Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: TeeJay am 29. February 2004, 22:26

Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: bscreator 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.
Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: bscreator 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
Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: Lizer 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.
Titel: Bootloader
Beitrag von: Lizer am 01. March 2004, 15:27
Ui, TeeJay war schneller...
Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: mastermesh 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 ;)
Titel: Bootloader
Beitrag von: bscreator am 01. March 2004, 18:02
Lizer, TeeJay und mastermash - habt Dank.
Titel: Bootloader
Beitrag von: neq 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
Titel: Bootloader
Beitrag von: bscreator 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
Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: TeeJay 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?
Titel: Bootloader
Beitrag von: bscreator am 01. March 2004, 21:39
Funktioniert einwandfrei - vielen Dank, TeeJay
Titel: Bootloader
Beitrag von: neq am 01. March 2004, 22:32
ja wäre cool wenn du so ne zusatzfunktion machen würdest.
Titel: Bootloader
Beitrag von: bscreator 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 ?
Titel: Bootloader
Beitrag von: TeeJay 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.
Titel: Bootloader
Beitrag von: bscreator 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!
Titel: Bootloader
Beitrag von: bscreator 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
Titel: Bootloader
Beitrag von: TeeJay am 02. March 2004, 22:15
Ich habe die Programme eigentlich nie selbst mit MASM ausprobiert.
Ich hab sie mir zwar mal angeschaut, aber das wars dann auch.

Auch wenn der Syntax für NASM anders ist als in dem Buch, so gibt das Buch doch eine Menge an Infos, die auch für NASM verwendet werden können.
Die Art und Weise wie ASM-Code formuliert wird, ändert sich ja nicht, lediglich der Syntax ist etwas anders.

Also kannst du aus dem Buch auch lernen wenn du NASM benutzt.

Wenn du das eBook haben willst, dann melde dich bei mir per Mail oder ICQ.
Titel: Bootloader
Beitrag von: bscreator am 02. March 2004, 22:16
Da hat mir wohl einer meiner Kumpels einen ziemlichen Sch...dreck erzählt. Schon das erste Programm läuft nicht. Hey TeeJay, wenn Du mit diesem Buch angefangen hast, welchen Assembler hast Du dann verwendet ?
Titel: Bootloader
Beitrag von: TeeJay am 02. March 2004, 22:45
Ich sag ja. Ich hab die Programme aus dem Buch nicht ausprobiert.
Ich hab erst mit NASM richtig angefangen in Assembler zu programmieren.

Und da musst du dir halt mal die Doku von NASM durchlesen. UNd dann kannst du auch den Syntax davon.
Titel: Bootloader
Beitrag von: lobmann am 08. March 2004, 18:29
moin TeeJay hab ma ne Frage zu deinem Bootloader bevor ich deinen entdeckt habe habe ich versucht selber einen zu schreiben. Is noch in arbeit
wollt mal fragen ob ich das RootDir und die FAT nich besser an die Stelle schreibe an die der Kernel geladen wird schreibe. das RootDir die FAT durchsuche alle Parameter die ich brauche auf den Stack pushe und dann den Kernel mit den werten vom stack lade. Den Bootloader brauch ich ja sowieso nur um den Kernel zu laden. Übersehe ich da was wichtiges oder wie ist deine bzw. eure Meinung dazu.
Titel: Bootloader
Beitrag von: lobmann am 08. March 2004, 18:31
Zu spät deutsches Sprache schweres Sprache
Titel: Bootloader
Beitrag von: TeeJay am 08. March 2004, 20:06
Hoi.
Du musst dir folgendes überlegen:
Zuerst musst du den Eintrag deiner Kerneldatei im Rootdir erstmal finden.
Dazu müsstest du die Sektoren in denen das RootDir enthalten ist komplett oder jeweils einzeln in den Speicher laden. (In meinem Loader hab ich sie einzeln geladen).
Wo du diese hinlädst ist vollkommen wurst, solange sie innerhalb der 1 MB Grenze sind und du nicht den Code deines Bootloaders überschreibst :)
Diese Daten müssen nicht ständig im SPeicher bleiben, da du das Rootdir ja nur einmal durchsuchen musst. Wenn du den Eintrag dort gefunden hast musst du aus diesem Eintrag den Startsektor der Kerneldatei lesen. Sobald du diesen hast ist das Rootdir uninteressant und alle Sektoren können dann auch im Speicher überschrieben werden.

Nun musst du die FAT-Tabelle lesen. Da diese jedoch etwas blöd aufgebaut ist (12 Bit pro Eintrag) empfielt es sich auf jeden Fall diese komplett in den Speicher zu lesen.

Von hier aus kannst du zwei wege gehen.
1. Du liest immer nur den Fat-Eintrag des nächsten Sektors und liest diesen Sektor dann in den Speicher. So hab ich das gemacht. Hier musst du dann aber aufpassen das du die FAT Tabelle im Speicher nicht überschreibst.

2. Du liest alle benötigen Fat Einträge und schreibst (wie von dir vorgeschlagen) alle der Reihe nach auf den Stack und liest dann alle Sektoren in einem Rutsch aus ohne jedesmal erst in der FAT nachzuschauen. In diesem Fall kann dann auch die FAT im Speicher überschrieben werden.

Also du siehst es gibt sehr unterschiedliche Methoden. Deine (2.) finde ich dabei auch garnicht mal so schlecht. Man muß dann nicht so mit dem Speicher aufpassen. Jedoch ist auch Methode 1 sehr einfach umzusetzen, da man ja 1 MB speicher für sich hat und das sollte genügen um da einzelne Bereiche auseinander zu halten.

Wäre gut möglich das dein Bootloader mit deiner Methode vielleicht sogar kompakter ist als meiner. Jedenfalls würde ich mir diesen gerne mal anschauen wenn er denn fertig ist und läuft!

mfg
TeeJay

PS: Find ich gut das du dir selbst mal Gedanken dazu machst und nicht einfach nur Software von anderen kopierst. Auch wenn das natürlich hier bei LowLevel nicht verboten ist. Jedoch ist der Lerneffekt wesentlich höher :)
Titel: Bootloader
Beitrag von: lobmann am 21. March 2004, 23:07
Moin TeeJay
Hab jetzt mal nen bischen rumprobiert
und ich bin überzeugt das deine Methode die bessere ist. Das Problem ist nämlich das man die FAT Anträge falschrum auf den Stack pushen muss. Ich könnte den Kernel dann nich gemütlich laden indem ich mir einfach jeden wert pope. Ich müsste die Werte entweder umdrehen was wohl hinsichtlich der begrenzten Ressourcen den code ziemlich aufblähen würde oder ich müsste die Werte anders adressieren was ich aber als  Lösung sehr unschön finde, Ich will ja eigentlich den Vorteil des Stacks nutzen was aber dann einfach quatsch wäre.

Also hab ich mir gedacht ich nehm mir einfach gedacht ich versuch deinen Bootloader zu optimieren.
Hab den jetz so umgeschrieben das er das ganze RootDir lädt. Der Vorteil ist das man hier die selbe Methode verwenden kann wie die um die Fattable zu laden. dadurch spart man wieder etwas code. Außerdem hab ich noch die Rechnung um aus der LHS die CHS zu machen geändert.

;Aus Logischer Sektornummer die CHS Adresse errechnen
    mov         ax,[Param1]
       xor         dx,dx
       mov        bx,18
       div         bx
       inc         dx
       mov                    [Var3],dx
       xor                dx,dx
       mov                    bx,2
       div                 bx
       mov                    [Var1],ax
      mov                [Var2],dx

Ich denke das ist viel zweckdienlicher als nochma komplett nen eigenen Loader zu schreiben die meisten Funktionen kann man ja eh nicht viel anders gestalten.
Titel: Bootloader
Beitrag von: lobmann am 21. March 2004, 23:08
ohja deutsch is schon manchmal schwer
Titel: Bootloader
Beitrag von: TeeJay am 21. March 2004, 23:20
Jo klar. Dazu ist der Code ja auch gedacht.

Das mit dem Laden des kompletten RootDirs hatte ich mir im nachhinein auch überlegt. Aber da hatte ich keine Lust mehr das umzuschreiben.


Aber find ich gut das du erstens mit meinem Code zurechtkommst und damit auch noch rumspielen kannst :)

Das mit deinem Stack hätte man wie folgt lösen können.
Du zählst einfach in einer Variable mit wie viele Einträge du auf den Stack pushst, und dann kannst du ja auch ganz einfach errechnen wo im Stack der erste Eintrag steht und dann jeweils immer den nächsten Laden.

Aber es gibt sicher 100 Möglichkeiten wie man das machen kann. Hauptsache ist ja das der Kernel geladen wird.
Titel: Bootloader
Beitrag von: joachim_neu am 22. March 2004, 08:16
hallo, ich kann den bootloader nicht aufrufen, da kommt immer

"Fehler:

Der angegebene Link exisitiert oder funktioniert nicht. Bitte schreiben Sie mir eine Mail an:

masta_ace_inc@gmx.de

Und teilen Sie mir das Problem mit.

Vielen Dank! "

Was soll ich machen?
Titel: Bootloader
Beitrag von: TeeJay am 22. March 2004, 14:13
Jo sorry. Ich hatte die Scripte und Verzeichnisse etwas umgestellt. Den Link hier im Thread hatte ich noch nicht umgestellt. Ist aber soeben passiert.