Autor Thema: [lowlevel magazin - ausgabe 1] tutorial - kernel zeigt wirre zeichen  (Gelesen 8214 mal)

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
also, wie als titel bereits geschrieben... mein kernel wird geladen, er zeigt einige textzeilen, anschliessend aber nur wirres zeug...

hier erst mal mein bereits etwas geänderter source:

boot.asm
; Bootloader Vers. 0.1.0
;
; Aufgaben:
; * Laden des Kernels und deren Start
; * Übergabe der Kontrolle des Computer an den Kernel

org 0x7C00 ; Startadresse des Bootloaders

jmp 0x0000:start ; Zu Startadresse springen

start:
cli ; Interups sind hier noch nicht erlaubt!
mov ax, 0x9000 ; Die Stackadresse auf 9000h Positionieren
mov ss, ax ; Den Stack an die Adresse 9000h anbinden
mov sp, 0 ; Den Stackpointer auf 0h Positionieren
sti ; Interups sind nun erlaubt!

; Nun suchen wir uns das Bootlaufwerk
mov [bootdrv], dl ; Der Name des Bootlaufwerks wird aus "DL" nach "[bootdrv] " verschoben

; Es wird zeit, den Kernel zu laden...
call load ; Wir rufen die Subroutine "load" auf. Diese läd für uns den Kernel
; Sobald der Kernel geladen ist, geht es hiernach weiter

mov ax, 0x1000 ; Unser Kernel ist an Adresse 1000h abgelegt worden.
; Diese Adresse muss natürlich gespeichert werden.
; Also verschieben wir die Startadresse in das Segement Register
mov es, ax ; Die Segement Register müssen aktualisiert werden
mov ds, ax
jmp 0x1000:0x0000 ; Der Kernel soll natürlich auch gestartet werden.
; Also springen wir zum Kernel

; Als nächstes einige Variablen, die die Arbeit erleichtern
bootdrv db 0 ; Wir sichern als erstes den Namen des startfähigen Laufwerks 0 nach "bootdrv"
loadmsg db "Lade den Kernel...",13,10,0 ; Wir hinterlegen eine Nachricht, damit der Benutzer sieht, das der Computer arbeitet...

; Damit der Benutzer sieht, das der Computer den Kernel läd, lassen wir dies auf dem Bildschirm ausgeben...
putstr:
lodsb ; Wir fangen einfach mal an, die Daten zu lesen
or al,al
jp short putstr ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Dies ist die Routine zum laden des Kernels...:
load:
mov ax, 0 ; Als erstes setzen wir das Bootlaufwerk zurück, um von ganz vorn lesen zu können
mov dl, [bootdrv] ;  Wir verschieben den Namen des Bootlaufwerks in den Speicher
int 13h ; Anschliessend sagen wir dem BIOS, das es vom Diskettenlaufwerk lesen soll
jc load ; Ist dies nicht gelungen, soll es dies erneut versuchen.
; Wir springen dazu einfach noch mal an den Anfang dieser Routine

; War dies erfolgreich, geht es hier weiter...
load1:
mov ax,0x1000 ; Wir markieren den Speicherbereich 0x1000 als Ziel für unserem Kernel
mov es,ax ; Wir aktualisieren die Segement Register. Somit sind sie bereit für unserem Kernel
mov bx, 0
mov ah, 2 ; Nun wirds interissant... Wir sagen den BIOS, das es etwas von einem Datenträger lesen soll
mov al, 5 ; Gelesen werden sollen die ersten 5 Sektoren...
mov cx, 2 ; Und zwar ab Cylinder 0, Sector 2
mov dh, 0 ; Mit hilfe von Head 0
mov dl, [bootdrv] ; Als Quelle dient das erste Bootlaufwerk (meistens Diskette)
jc load1 ; Hat nicht geklappt? Dann noch mal von vorn...

; Wenn das Lesen erfolgreich war, gehts hier weiter...
mov si,loadmsg ; Als erstes holen wir uns die Bootmsg aus dieser Variable.
; Das ist die Nachricht, die der Benutzer auf dem Bildschirm sehen soll...
call putstr ; Dann geben wir diese mit Hilfe dieser Suroutine aus...
retn ; Dann schliessen wir das Laden des Kernels hier ab...

; Nun müssen wir den Bootloader nur noch die richtige Größe bringen.
; Um es kurz zu machen: Der Bootloader darf nur 512 Bytes groß sein.
; Also bringen wir unserem Bootloader in Form...
times 512-($-$$)-2 db 0

; Anschliessend markieren wir den Datenträger als Bootähig...
dw 0AA55h

; Das wars...
; Das ist unser Bootloader...

kernel.asm
; miniKernel Ver.s 0.1.0
;
; Aufgaben:
; * Kern des Betriebssystems
;   * Das heist:
;      + Stellt Grundlegende Funktionen und Routinen desBetriebssystems bereit
;      + Verwaltet Grundlegende Funktionen der Datenträger,
;         insbesondere das Lese,Schreiben und Ändern von Dateien und Daten
;      + Verwaltet den Speicher, Threats etc..
;
; Kernel- Typ:
; * Monolitsch
;   + Nur in der Start- bzw. Entwicklungsphase
;      Später wir der Kernel Modular Struckturiert sein....

mov ax, 0x1000 ; Den Kernel an Adresse 1000h Positionieren
mov ds, ax ; Die Segement Register aktualisieren
mov es, ax

start:
; Anschliesend verwenden wir die Subroutine "putstrg", um Benutzer- Nachrichten auszugeben
mov si,msg ; Wir holen als erstes die Nachricht
call putstr ; Und diese geben wir nun aus...

mov si,msg_boot ; Wir holen uns eine weitere Nachricht...
call putstr ; Auch diese geben wir nun aus...

mov si, msg_boot2 ; Wir holen uns eine weitere Nachricht...
call putstr ; Auch diese geben wir nun aus..

call getkey ; Hier rufen wir nun eine Subroutine auf, die auf einem Tastendruck wartet...
jmp reboot ; Weiter gehts zu einer Subrouten, die den PC neustartet

;  Wir speichern die Nachrichten, in den nachfolgenden Variablen...:
msg db "Willkommen beim minOS Version 0.1.0",13,10,0
msg_boot db "Kernel wurde erfolgreich geladen...",10,0
msg_boot2 db "Druecke eine Taste, um den Computer neu zu starten...",10,0

; Es wir Zeit, die Nachrichten auszugeben...:
putstr:
lodsb ; Beginne zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Diese Funktion starte den Computer, nach einem Tastendruck, neu
getkey:
mov ah, 0 ; Prozessor Funktion 0, oder anders gesagt, Neustart, ausführen
; Dieser Aufruf bereitet den Prozessor hierfür vor
int 0x16 ; Dieser Befehl löd den Reboot Befehl aus
ret

reboot:
jmp 0xffff:0x0000 ; Alle Befehle entfernen, sowie dem Prozessor neustarten

; Das wars....
; Das ist unserer Mini- Kernel...

entweder wird das laden der textzeilen nicht korrekt abgeschlossen, oder ich habe den aufruf der funktion zum neustarten falsch intergriert...

wo liegt hier der fehler...?

---

ps: sind meine, für mich intergrierten, kommentare korrekt? ich meine die erklärungen der anweisungen. damit will ich sicherstellen, das ich das tutorial richtig verstanden habe...

[edit]
ich füge mal noch hinzu, das ich unter windows xp mit nasm kompiliere und auch, als vergleich, den code aus dem magazin per c&p in notepad++ kopiert und nasm diesen dann assemblieren lassen habe. da tritt seltsamerweise das selbige problem auf...
« Letzte Änderung: 22. July 2008, 13:00 von Gamepower »

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
Hi,

In der boot.asm steht:

jp short putstr
Aber wieso jp? Ich würde wie du es auch in der kernel.asm getan hast jz nehmen und vor allen Dingen putstrd nicht putstr, also so:

jz short putstrd
So mal schauen, evtl. finde ich noch mehr. ;-)


EDIT: So noch etwas gefunden. In der routine load1 fehlt der Aufruf des int 13h. Also es sollte so aussehen:

load1:
mov ax,0x1000 ; Wir markieren den Speicherbereich 0x1000 als Ziel für unserem Kernel
mov es,ax ; Wir aktualisieren die Segement Register. Somit sind sie bereit für unserem Kernel
mov bx, 0
mov ah, 2 ; Nun wirds interissant... Wir sagen den BIOS, das es etwas von einem Datenträger lesen soll
mov al, 5 ; Gelesen werden sollen die ersten 5 Sektoren...
mov cx, 2 ; Und zwar ab Cylinder 0, Sector 2
mov dh, 0 ; Mit hilfe von Head 0
mov dl, [bootdrv] ; Als Quelle dient das erste Bootlaufwerk (meistens Diskette)
int 13h
jc load1

EDIT: Ich habs mal getestet. Also auf VMware funktionierts, auf Qemu und VirtualBox leider nicht. Weiß ich jetzt leider auch nicht warum es dort nicht funktioniert.

EDIT: Habs jetzt mal auf Bochs getestet. Da funktioniert es.

bitmaster
« Letzte Änderung: 22. July 2008, 22:41 von bitmaster »
In the Future everyone will need OS-64!!!

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
Hi,

In der boot.asm steht:

jp short putstr
Aber wieso jp? Ich würde wie du es auch in der kernel.asm getan hast jz nehmen und vor allen Dingen putstrd nicht putstr, also so:

jz short putstrd

So mal schauen, evtl. finde ich noch mehr. ;-)


EDIT: So noch etwas gefunden. In der routine load1 fehlt der Aufruf des int 13h. Also es sollte so aussehen:

load1:
mov ax,0x1000 ; Wir markieren den Speicherbereich 0x1000 als Ziel für unserem Kernel
mov es,ax ; Wir aktualisieren die Segement Register. Somit sind sie bereit für unserem Kernel
mov bx, 0
mov ah, 2 ; Nun wirds interissant... Wir sagen den BIOS, das es etwas von einem Datenträger lesen soll
mov al, 5 ; Gelesen werden sollen die ersten 5 Sektoren...
mov cx, 2 ; Und zwar ab Cylinder 0, Sector 2
mov dh, 0 ; Mit hilfe von Head 0
mov dl, [bootdrv] ; Als Quelle dient das erste Bootlaufwerk (meistens Diskette)
int 13h
jc load1

EDIT: Ich habs mal getestet. Also auf VMware funktionierts, auf Qemu und VirtualBox leider nicht. Weiß ich jetzt leider auch nicht warum es dort nicht funktioniert.

EDIT: Habs jetzt mal auf Bochs getestet. Da funktioniert es.

bitmaster

thx :) da hab ich doch glatt tippfehler drinn und auch eine zeile vergessen...

qemu stürzt nach der fehlerbereinigung ab... auf mein noteboot (p3 @600mhz) läuft alles so wie es sein soll. nur die 3. zeile meiner textausgabe ist ziemlich weit nach rechts gerutscht. aber, das korrigiere ich noch.

wie sieht es mit meinem kommentaren aus. hab ich das alles richtig verstanden (siehe kommentare) ?

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
boot.asm:

Zitat
Der Name des Bootlaufwerks wird aus "DL" nach "[bootdrv] " verschoben
Na ja, ich würde nicht Name sagen. Eher BIOS-Laufwerknummer oder so etwas.

Zitat
Unser Kernel ist an Adresse 1000h abgelegt worden.
Nee, der Kernel befindet sich an Adresse 10000h (also eine Null mehr). Ich weiß nicht, ob du dich schon mit der Adressierung im Real-Mode beschäftigt hast. Um im RM (Real-Mode) ganze 1 MByte ansprechen zu können wird so adressiert: Segmentregister mal 16 (also mal 10h) plus Offset. Das heißt in deinem Fall: 1000h * 10h + 0 = 10000h.

Zitat
Wir sichern als erstes den Namen des startfähigen Laufwerks 0 nach "bootdrv"
Wie schon gesagt, Name eher nicht.

Zitat
loadmsg db "Lade den Kernel...",13,10,0 ; Wir hinterlegen eine Nachricht, damit der Benutzer sieht, das der Computer arbeitet...
Ist nicht so wichtig, aber wenn du schreibst "Lade den Kernel", dann würde ich die Nachricht schon vor dem Laden des Kernels ausgeben (ansonsten vielleicht "Kernel wurde geladen" oder so).

Zitat
Wir verschieben den Namen des Bootlaufwerks in den Speicher
Wie oben schon gesagt, nicht Name. Aber in dem Speicher wird dort auch nichts verschoben. Eher vom Speicher in dem Register dl kopiert.

Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.

kernel.asm:

Zitat
Den Kernel an Adresse 1000h Positionieren
Den Kernel positionieren? KA würde ich anders ausdrücken.

Zitat
Prozessor Funktion 0...
Nee Funktion Null des BIOS-Interrupts 16h.

Zitat
Dieser Befehl löd den Reboot Befehl aus
Nee, der "Befehl" hat mit dem reboot nichts zu tun. Er wartet bis eine Taste (außer Systemtasten wie Strg, Alt etc.) gedrückt wird und kopiert dessen Scancode nach ah und den evtl. vorhandenen ASCII-Code nach al.

Zitat
Alle Befehle entfernen, sowie dem Prozessor neustarten
Hmm... Befehle entfernen hört sich komisch an.


Der Text wird so "komisch" ausgegeben, weil du bei msg_boot und msg_boot2 vor/nach der 10 (zeile = zeile + 1) die 13 (spalte = 0) vergessen hast.


So, hoffe dass ich dir einwenig helfen konnte. Immer am Ball bleiben. :-)

bitmaster
In the Future everyone will need OS-64!!!

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
boot.asm:

Zitat
Der Name des Bootlaufwerks wird aus "DL" nach "[bootdrv] " verschoben
Na ja, ich würde nicht Name sagen. Eher BIOS-Laufwerknummer oder so etwas.
hmmm, kann man auch als "name" verstehen. da schau ich mal ins buch "moderne betriebssysteme", sobald es meins it :)

Zitat
Unser Kernel ist an Adresse 1000h abgelegt worden.
Nee, der Kernel befindet sich an Adresse 10000h (also eine Null mehr). Ich weiß nicht, ob du dich schon mit der Adressierung im Real-Mode beschäftigt hast. Um im RM (Real-Mode) ganze 1 MByte ansprechen zu können wird so adressiert: Segmentregister mal 16 (also mal 10h) plus Offset. Das heißt in deinem Fall: 1000h * 10h + 0 = 10000h.
darüber weiss ich dann wohl doch noch etwas zuwenig... ich gehe halt davon aus, das der speicherplatz des kernels an dieser adresse beginnt...

Zitat
Wir sichern als erstes den Namen des startfähigen Laufwerks 0 nach "bootdrv"
Wie schon gesagt, Name eher nicht.
wie schon gesagt, sobald das buch da ist, weiss ich mehr darüber...

Zitat
loadmsg db "Lade den Kernel...",13,10,0 ; Wir hinterlegen eine Nachricht, damit der Benutzer sieht, das der Computer arbeitet...
Ist nicht so wichtig, aber wenn du schreibst "Lade den Kernel", dann würde ich die Nachricht schon vor dem Laden des Kernels ausgeben (ansonsten vielleicht "Kernel wurde geladen" oder so).
Zitat
hmm, da setze ich wohl noch eine zweite nachricht vor der laderoutine des kernels und passe diese hier an...

Zitat
Wir verschieben den Namen des Bootlaufwerks in den Speicher
Wie oben schon gesagt, nicht Name. Aber in dem Speicher wird dort auch nichts verschoben. Eher vom Speicher in dem Register dl kopiert.
da kommen wir dem ganzen schon etwas näher. danke :)

Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.
naja, ohne die adresse auch keine nachricht, oder...? aber, gut zu wissen :)

kernel.asm:

Zitat
Den Kernel an Adresse 1000h Positionieren
Den Kernel positionieren? KA würde ich anders ausdrücken.
ok, darum kümmere ich mich noch...

Zitat
Prozessor Funktion 0...
Nee Funktion Null des BIOS-Interrupts 16h.
ok, dann heist es, bücher über das bios noch mal rausholen...

Zitat
Dieser Befehl löd den Reboot Befehl aus
Nee, der "Befehl" hat mit dem reboot nichts zu tun. Er wartet bis eine Taste (außer Systemtasten wie Strg, Alt etc.) gedrückt wird und kopiert dessen Scancode nach ah und den evtl. vorhandenen ASCII-Code nach al.
ah, falsch verstanden.... danke dir :)

Zitat
Alle Befehle entfernen, sowie dem Prozessor neustarten
Hmm... Befehle entfernen hört sich komisch an.
passt evtl. "befehlsregister leeren"...?

Der Text wird so "komisch" ausgegeben, weil du bei msg_boot und msg_boot2 vor/nach der 10 (zeile = zeile + 1) die 13 (spalte = 0) vergessen hast.
das hatte ich schon bemerkt. ich hab die zeilen und die ergebnisse verglichen. ich hab einfach nur die "13" entsprechend eingefügt. danke für die erklärung der spalten und zeilen. das werde ich später noch für weitere ausgaben brauchen...

So, hoffe dass ich dir einwenig helfen konnte. Immer am Ball bleiben. :-)

bitmaster

einwenig? ja :) jetzt, wo man "blut gelegt" hat, gehts natürlich weiter ;)

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
hmmm, kann man auch als "name" verstehen. da schau ich mal ins buch "moderne betriebssysteme", sobald es meins it :)
Ich würde Name für falsch halten, einfach weil es nicht aus "lesbaren" Zeichen besteht. Das Buch von Tannenbaum wird dich dahingehend auch nicht wesentlich weiterbringen. Es beschäftigt sich eher von abstrakterer Sicht mit Betriebssystemen.

Zitat
Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.
naja, ohne die adresse auch keine nachricht, oder...? aber, gut zu wissen :)
Zwischen deiner Hausnummer und deinem Haus ist m.E. schon nochmal ein großer Unterschied. Zumindest macht es einen Unterschied ob ich deine Hausnummer oder dein Haus besitze. :wink:  :-P

Zitat
Prozessor Funktion 0...
Nur um das klarzustellen. Die Funktion wird vom BIOS und nicht vom Prozessor zu Verfügung gestellt. Der Prozessor stellt nur die Instruktion "int" zur Verfügung, hinter welcher sich ein Sprung ins BIOS verbirgt. Wobei man den Prozessor dahin springen lassen kann wo man will, man muss nur die IVT (Interrupt Vector Table) entsprechend anpassen. Das BIOS hat die halt beim Start so erstellt, dass die einzelnen Interrupts auf BIOS-routinen zeigen.

Zitat
Zitat
Alle Befehle entfernen, sowie dem Prozessor neustarten
Hmm... Befehle entfernen hört sich komisch an.
passt evtl. "befehlsregister leeren"...?
Eher Sprung zum BIOS-Einsprungpunkt. 0xFFFF:0x0000 _wäre_ nämlich die Adresse in CS:IP nach einem Prozessor-Reset. An dieser Adresse ist das BIOS eingeblendet, welches dann den ganzen Hardwaregobledigu initialisiert.

Zitat
einwenig? ja :) jetzt, wo man "blut gelegt" hat, gehts natürlich weiter ;)
ROFL... es heißt "Blut geleckt"...
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
hmmm, kann man auch als "name" verstehen. da schau ich mal ins buch "moderne betriebssysteme", sobald es meins it :)
Ich würde Name für falsch halten, einfach weil es nicht aus "lesbaren" Zeichen besteht. Das Buch von Tannenbaum wird dich dahingehend auch nicht wesentlich weiterbringen. Es beschäftigt sich eher von abstrakterer Sicht mit Betriebssystemen.
das ist mir schon klar, das man es "nicht lesen" kann... aber, es hat ja eine bezeichnung. ob es nun "0", oder "a" (...) ist, lassen wir mal dahin gestellt. man will ja die bezeichung "nehmen" und diese übergeben...

Zitat
Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.
naja, ohne die adresse auch keine nachricht, oder...? aber, gut zu wissen :)
Zwischen deiner Hausnummer und deinem Haus ist m.E. schon nochmal ein großer Unterschied. Zumindest macht es einen Unterschied ob ich deine Hausnummer oder dein Haus besitze. :wink:  :-P
das stimmt. hier aber brauchen wir die adresse, um uns die nachricht holen zu können... oder, denke ich da jetzt gerade in die falsche richtung...

Zitat
Prozessor Funktion 0...
Nur um das klarzustellen. Die Funktion wird vom BIOS und nicht vom Prozessor zu Verfügung gestellt. Der Prozessor stellt nur die Instruktion "int" zur Verfügung, hinter welcher sich ein Sprung ins BIOS verbirgt. Wobei man den Prozessor dahin springen lassen kann wo man will, man muss nur die IVT (Interrupt Vector Table) entsprechend anpassen. Das BIOS hat die halt beim Start so erstellt, dass die einzelnen Interrupts auf BIOS-routinen zeigen.
hmm, ok. wieder was gelernt.

Zitat
Zitat
Alle Befehle entfernen, sowie dem Prozessor neustarten
Hmm... Befehle entfernen hört sich komisch an.
passt evtl. "befehlsregister leeren"...?
Eher Sprung zum BIOS-Einsprungpunkt. 0xFFFF:0x0000 _wäre_ nämlich die Adresse in CS:IP nach einem Prozessor-Reset. An dieser Adresse ist das BIOS eingeblendet, welches dann den ganzen Hardwaregobledigu initialisiert.
hmm, habs dann wohl falsch verstanden... wieder was gelernt.

Zitat
einwenig? ja :) jetzt, wo man "blut gelegt" hat, gehts natürlich weiter ;)
ROFL... es heißt "Blut geleckt"...
war wohl doch noch etwas früh, oder die nacht zu lang ;) hab etwas weiter gebastelt und das 2. tutorial gelesen...

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
Zitat
Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.
naja, ohne die adresse auch keine nachricht, oder...? aber, gut zu wissen :)
Zwischen deiner Hausnummer und deinem Haus ist m.E. schon nochmal ein großer Unterschied. Zumindest macht es einen Unterschied ob ich deine Hausnummer oder dein Haus besitze. :wink:  :-P
das stimmt. hier aber brauchen wir die adresse, um uns die nachricht holen zu können... oder, denke ich da jetzt gerade in die falsche richtung...
Ja, aber wir "holen" uns die Nachricht mit der Anweisung überhaupt nicht. In das Register wird nunmal die Addresse der Nachricht geschrieben. Auf die Nachricht selber wird hier garnicht zugegriffen, das macht erst der BIOS-Interrupt.
« Letzte Änderung: 23. July 2008, 11:50 von Korona »

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
Zitat
Zitat
Als erstes holen wir uns die Bootmsg aus dieser Variable.
Ich würde sagen die Adresse der Bootmsg, nicht die Bootmsg selber.
naja, ohne die adresse auch keine nachricht, oder...? aber, gut zu wissen :)
Zwischen deiner Hausnummer und deinem Haus ist m.E. schon nochmal ein großer Unterschied. Zumindest macht es einen Unterschied ob ich deine Hausnummer oder dein Haus besitze. :wink:  :-P
das stimmt. hier aber brauchen wir die adresse, um uns die nachricht holen zu können... oder, denke ich da jetzt gerade in die falsche richtung...
Ja, aber wir "holen" uns die Nachricht mit der Anweisung überhaupt nicht. In das Register wird nunmal die Addresse der Nachricht geschrieben. Auf die Nachricht selber wird hier garnicht zugegriffen, das macht erst der BIOS-Interrupt.

hmmm, also ich würde das auch noch als "holen" bezeichnen. auch, wenn dies das bios übernimmt... als "logischen" schritt würde ich da mal sagen... kann schon sein, das ich hier "logisch" falsch denke ;)

Gamepower

  • Beiträge: 41
    • Profil anzeigen
Gespeichert
ich habe den bootloader etwas umgebaut..

; Bootloader Vers. 0.1.0
;
; Aufgaben:
; * Laden des Kernels und deren Start
; * Übergabe der Kontrolle des Computer an den Kernel

org 0x7C00 ; Startadresse des Bootloaders

jmp 0x0000:start ; Zu Startadresse springen

start:
cli ; Interups sind hier noch nicht erlaubt!
mov ax, 0x9000 ; Die Stackadresse auf 9000h Positionieren
mov ss, ax ; Den Stack an die Adresse 9000h anbinden
mov sp, 0 ; Den Stackpointer auf 0h Positionieren
sti ; Interups sind nun erlaubt!

; Nun suchen wir uns das Bootlaufwerk
mov [bootdrv], dl ; Die Nummer des Bootlaufwerks wird aus "DL" nach "[bootdrv] " verschoben

mov si,BootMsg ; Nachricht beim Start ausgeben
call putstr ; Routine zum Ausgeben der Nachricht aufrufen

mov si,LoadMsg ; Nachricht zum Laden des Kernels ausgeben
call putstr ; Die Routine zum Ausgen der Nachricht erneut aufrufne

; Es wird zeit, den Kernel zu laden...
call load ; Wir rufen die Subroutine "load" auf. Diese läd für uns den Kernel
; Sobald der Kernel geladen ist, geht es hiernach weiter

mov ax, 0x1000 ; Unser Kernel ist an Adresse 10000h.
; Die Startadresse ergibt sich so:
; Segementregister x 16 (also mal 10h) + Offset
; Das heist: 1000h x 10h + 0
; Diese Adresse muss natürlich gespeichert werden.
; Also verschieben wir die Startadresse in das Segement Register
mov es, ax ; Die Segement Register müssen aktualisiert werden
mov ds, ax
jmp 0x1000:0x0000 ; Der Kernel soll natürlich auch gestartet werden.
; Also springen wir zum Kernel

; Als nächstes einige Variablen, die die Arbeit erleichtern
bootdrv db 0 ; Wir sichern als erstes die Nummer des startfähigen Laufwerks 0 nach "bootdrv"
BootMsg db "MiniLoader Vers. 0.1.0", 13,10,0
LoadMsg db "Lade den Kernel", 13,10,0
LoadDoneMsg db "Fertig. Starte den Kernel...",13,10,0 ; Wir hinterlegen eine Nachricht, damit der Benutzer sieht, das der Computer arbeitet...

; Damit der Benutzer sieht, das der Computer den Kernel läd, lassen wir dies auf dem Bildschirm ausgeben...
putstr:
lodsb ; Wir fangen einfach mal an, die Daten zu lesen
or al,al
jz short putstrd ; Muss noch etwas gelesen werden, oder ist alles gelesen worden...?
; Wenn alles gelesen wurde, dann ENDE!
mov ah,0x0E ; Ruft die Funktion 0x0E des BIOS auf
mov bx,0x0007 ; Nicht notwendig, aber dennoch... Setzt das Atribut
int 0x10 ; Schreiben des Textes auf den Bildschirm
jmp putstr ; Solange noch etwas zu lesen ist, wird diese Subroutine neu gestartet und weiter gelesen
putstrd:
retn ; Fertig mit dem lesen? wenn ja, dann geht es hier zurück zur Hauptroutine

; Dies ist die Routine zum laden des Kernels...:
load:
mov ax, 0 ; Als erstes setzen wir das Bootlaufwerk zurück, um von ganz vorn lesen zu können
mov dl, [bootdrv] ;  Wir verschieben den Namen des Bootlaufwerks in den Speicher
int 13h ; Anschliessend sagen wir dem BIOS, das es vom Diskettenlaufwerk lesen soll
jc load ; Ist dies nicht gelungen, soll es dies erneut versuchen.
; Wir springen dazu einfach noch mal an den Anfang dieser Routine

; War dies erfolgreich, geht es hier weiter...
load1:
mov ax,0x1000 ; Wir markieren den Speicherbereich 0x1000 als Ziel für unserem Kernel
mov es,ax ; Wir aktualisieren die Segement Register. Somit sind sie bereit für unserem Kernel
mov bx, 0
mov ah, 2 ; Nun wirds interissant... Wir sagen den BIOS, das es etwas von einem Datenträger lesen soll
mov al, 5 ; Gelesen werden sollen die ersten 5 Sektoren...
mov cx, 2 ; Und zwar ab Cylinder 0, Sector 2
mov dh, 0 ; Mit hilfe von Head 0
mov dl, [bootdrv] ; Als Quelle dient das erste Bootlaufwerk (meistens Diskette)
int 13h
jc load1 ; Hat nicht geklappt? Dann noch mal von vorn...

; Wenn das Lesen erfolgreich war, gehts hier weiter...
mov si,LoadDoneMsg ; Als erstes holen wir uns die Bootmsg aus dieser Variable.
; Das ist die Nachricht, die der Benutzer auf dem Bildschirm sehen soll...
call putstr ; Dann geben wir diese mit Hilfe dieser Suroutine aus...
retn ; Dann schliessen wir das Laden des Kernels hier ab...

; Nun müssen wir den Bootloader nur noch die richtige Größe bringen.
; Um es kurz zu machen: Der Bootloader darf nur 512 Bytes groß sein.
; Also bringen wir unserem Bootloader in Form...
times 512-($-$$)-2 db 0

; Anschliessend markieren wir den Datenträger als Bootähig...
dw 0AA55h

; Das wars...
; Das ist unser Bootloader...

die textausgabe vor dem laden des kernels funktioniert.

evtl kann ja jemand den code gebrauchen :)

 

Einloggen