Autor Thema: [Anfänger] Keine Ausgabe  (Gelesen 18008 mal)

Azi

  • Beiträge: 47
    • Profil anzeigen
Gespeichert
« Antwort #20 am: 11. November 2005, 09:29 »
So, jetzt möchte ich den Kernel laden. Ich könnte einfach den Code aus der Lowlevel 1 nehmen, aber ich möchte es wenigstens verstehen, was ich aber leider nicht tue. Also:

...
;Lade unseren Kernel
call load          ;Ok, das verstehe ich

;Springe zu diesem Kernel
mov ax, 0x1000 ; Die Adresse des Programms          ;Ist der Kernel jetzt da?
...
push ax          ;Gerettet
mov ax, 0          ;jetzt ist 0
push ax          ;Wiederhergestellt --> Was hat das jetzt gebracht?
retf
...
; Lade den Kernel vom Bootlaufwerk
load:

; Diskdrive reset (Interrupt 13h, 0)          ;Wieso?
push ds            ; Sichere DS          ;Wieso?
...
pop ds             ; DS wiederherstellen          ;Siehe Kommentar über diesem
jc load            ; Geht nicht? -> Noch mal!          ;Wieso sollte es dann plötzlich klappen?

load1:
...
; Sektoren lesen (Interrupt 13h, 2)          ;Was bringt das?
...
mov dx, 0       ; Head=0, Laufwerk=0          ;Wieso Laufwerk=0?
int 13h         ; ES:BX =  Daten vom Laufwerk          ;???
jc load1        ; Fehler? Noch mal!          ;Wieso sollte es dann plötzlich klappen?
...

Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen nicht.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.

Thoth

  • Beiträge: 62
    • Profil anzeigen
Gespeichert
« Antwort #21 am: 11. November 2005, 12:41 »
mov ax, 0x1000 ; Die Adresse des Programms          ;Ist der Kernel jetzt da?

Jep, denn in load wird das als die Startadresse für den Kernel angegeben:


mov ax,0x1000 ; ES:BX = 10000



push ax          ;Gerettet
mov ax, 0          ;jetzt ist 0
push ax          ;Wiederhergestellt --> Was hat das jetzt gebracht?
retf


Es wird gar nichts wiederhergestellt, es wird nur einmal 0x1000 und dann 0 mit Hilfe des Registers ax auf den Stack gepusht, weil retf sowohl eine Segment- als auch eine Offsetadresse auf selbigem erwartet. Diese werden dann vom Stack genommen und dorthin gejumpt. Man "kehrt also zum Kernel zurück". Das mag etwas komisch klingeln, weil man da ja gar nicht herkam, aber solange die richtige Adresse auf dem Stack liegt ist das der CPU egal.


; Diskdrive reset (Interrupt 13h, 0)          ;Wieso?
push ds            ; Sichere DS          ;Wieso?
...
pop ds             ; DS wiederherstellen          ;Siehe Kommentar über diesem
jc load            ; Geht nicht? -> Noch mal!          ;Wieso sollte es dann plötzlich klappen?


Zum ersten Wieso: sicher ist sicher, also lieber mal resetten, denn dann weiß man genau in welchem Zustand sich das Laufwerk befindet.
Zum zweiten und dritten: Da bin ich mir nicht sicher, ich nehme aber einfach mal an, dass int 13 ds benötigt und man es deshalb woanders zwischenspeichern muss.
Zum dritten: Naja, vielleicht hatte das Laufwerk gerade wichtigeres zu tun und das BIOS konnte den Befehl deshalb nicht ausführen - dann muss man es einfach so lange weiter versuchen, bis das Laufwerk frei ist.


; Sektoren lesen (Interrupt 13h, 2)          ;Was bringt das?
...
mov dx, 0       ; Head=0, Laufwerk=0          ;Wieso Laufwerk=0?
int 13h         ; ES:BX =  Daten vom Laufwerk          ;???
jc load1        ; Fehler? Noch mal!          ;Wieso sollte es dann plötzlich klappen?
...


Zum Was: Naja, wir wollen doch den Kernel laden. Der ist aber noch nicht im Speicher, sondern nur auf der Floppy. Von der können wir den Kernel aber nicht direkt ausführen, also müssen wir ihn vom Floppy in den Speicher hauen. Und da ein Sektor die kleinste Einheit auf einer solchen Diskette ist, die man ansprechen kann machen wir das eben sektorweise.

Wieso Laufwerk=0: naja, das ist normalerweise das erste. Da ich mir hier aber auch gerade nicht so sicher bin verweise ich einfach mal hierauf.

Daten vom Laufwerk ???: Nun, der Biosinterrupt liest ja brav Sektoren von der Diskette ein, aber irgendwo müssen die ja auch hin und das ist eben definitionsgemäß (so ist die Funktion halt aufgebaut) an dieser Stelle.

Wieso sollte es dann plötzlich klappen? siehe oben.



Da ich aber auch ein blutiger Anfänger in Sachen Systemprogrammierung bin und das meiste meines Wissens auch nur von dieser Seite hier habe empfehle ich dir zusätzlich eine zweite Meinung von jemandem, der sich auskennt einzuholen *g*[/code]
Madness isn't a bug - it's a feature

Azi

  • Beiträge: 47
    • Profil anzeigen
Gespeichert
« Antwort #22 am: 11. November 2005, 12:53 »
Na, das soll nach einem blutigem Anfänger klingn? Anfänger mag sein (das kann ich nicht beurteilen), aber der blutige Anfänger hier bin wohl ich!

Zu den Sektoren-Einlese-Teil:
Woher soll man wissen, in welchem Sektor der Kernel liegt bzw. wieviele er belegt?

/Edit: Vielen Dank für die Mühe, die du dir gemacht hast, denn der Teil, den ich dir zeigte, war nicht ganz wenig.

Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen nicht.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.

Thoth

  • Beiträge: 62
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 11. November 2005, 15:33 »
Zitat
Na, das soll nach einem blutigem Anfänger klingn?


:oops: Ich fühle mich geehrt, aber alles was ich geschrieben habe findest du auch hier auf lowlevel, oder ist zumindest von hier verlinkt.

Wegen den Sektoren: bei den kleinen anfänglichen Projekten sollte es reichen, den Kernel einfach mit dem Bootsektor zusammenzukopieren und als eins auf die Diskette zu schreiben. In dem Fall liegt der Kernel logischerweise in den Sektoren genau hinter dem Bootsektor und wie viele das sind kann man ja an der Größe der Kerneldatei (ein Sektor = 512 Bytes, aber das ist  glaub ich eh klar *g*) leicht erkennen.
Wenn man dann später was größeres plant und auch ein Dateisystem (FAT12 zum Beispiel, oder auch ein selbsterdachtes) benutzen möchte, dann steht der Kernel normalerweise in einem vordefinierten Verzeichnis und hat einen vordefinierten Namen (oder zumindest existiert eine vordefinierte Datei mit diesen Informationen, wie z.B. boot.ini bei Windows NT) und dann muss der Bootloader halt auch das Dateisystem kennen und selbiges nach einer Datei mit diesem Namen durchsuchen. Und da im Dateisystem logischerweise auch die Sektoren stehen, kann man die dann genauso wie sonst auch einlesen.
Madness isn't a bug - it's a feature

Azi

  • Beiträge: 47
    • Profil anzeigen
Gespeichert
« Antwort #24 am: 11. November 2005, 15:45 »
Hat mal einer einen Tipp? Was soll ich zuerst machen:
Einen Kernel oder ein Dateisystem reinbringen? Evtl. wäre es später einfacher, sofort mit dem Dateisystem zu beginnen...

Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen nicht.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 11. November 2005, 15:52 »
Du kannst jederzeit wechseln. Dem Kernel selbst ist es egal, wie er geladen wird. Das heißt du kannst sobald du Lust hast deinen Bootloader umschreiben und bis dahin die Methode ohne FS nehmen. Alternativ kannst du dir auch mal GRUB anschausen.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #26 am: 11. November 2005, 17:10 »
Zitat von: Azi
Hat mal einer einen Tipp? Was soll ich zuerst machen:
Einen Kernel oder ein Dateisystem reinbringen? Evtl. wäre es später einfacher, sofort mit dem Dateisystem zu beginnen...
Also etwas zum laden brauchst du ja schon. Und das ist nun einmal der Kernel. Also ich habe mit dem Kernel angefangen. Am einfachsten ist es diesen auf den 2. Sektor der Diskette zu kopieren und ihn (den Kernel also) mit dem int 13h zu laden. Hier ein Beispielcode:

mov ax,1000h
mov es,ax ;Segment
mov ah,02h
mov al,01h ;anzahl der Sektoren, später vergrößern
xor bx,bx ;Offset
mov cx,0002h ;Spur=null, Sektor=2
xor dh,dh ;Seite=null
xor dl,dl ;laufwerk null=A:
int 13h
jc error ;falls fehler
mov ax,1000h
mov ds,ax
push 1000h
push 0000h
retf ;zum kernel springen


Dieser Code läd den zweiten Sektor einer Diskette an Adresse 1000:0000 = 10000h und springt dort hin. Also wenn du vorher deinen Kernel auf den 2. Sektor schreibtst kannst du so deinen Kernel laden. Später wenn du dann immer besser wirst kannst du ja ein Dateisystem intergrieren.
In the Future everyone will need OS-64!!!

Azi

  • Beiträge: 47
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 11. November 2005, 17:45 »
Dann ist ja gut, jetzt mache ich mich an den Kernel!

Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen nicht.

Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.

 

Einloggen