Bootloader: prekernel laden: ich bin total verzweifelt
-
Ich bin verzweifelt, am Boden zerstört.
Ich habe nen Bootloader geschrieben, der funktioniert auch. So. Soweit so gut. Jetzt möchte ich den Prekernel laden, der sich auf der Diskette genau hinter dem Bootloader befindet, also in Sektor 0x01 (muss ja so sein, bootloader ist 512 byte groß=1Sektor, startsektor ist 0x00, also muss hinter dem Bootloader Sektor 0x01 sein). Der Prekernel ist exakt 2048 byte groß, also 4 Sektoren. Ich benuzte folgenden Code um den Prekernel zu laden(Auszug):
[code]
mov ah, 0x00 ; Interrupt 13h Funktion zum Reset des Diskettenlaufwerks auswaehlen
int 0x13 ; Reset Diskettenlaufwerk
jc fehler_drivereset ; Wenn CFlag gesetzt ist ein Fehler aufgetretenmov si, success_drivereset
call putstrmov cl, 0x01 ; Start Sektor sektor 1, bei 512 bytes!!!
mov ax, 0x2000
mov es, ax ; Ort, wo Kernel hingeladen wird
mov bx, 0x00 ; Offset, an dem begonnen werden soll, den Kernel hinzuladen
mov al, 0x04 ; Anzahl der zu lesenden Sektoren 2048 byte !!!;
; NEU ENDE!
;sektor_einlesen:
mov ah, 0x02 ; Interrupt 13h Funktion zum Lesen von Sektoren
mov ch, 0x00 ; Spur 0
mov dl, 0x00 ; Laufwerks Nummer (0 = Erstes Diskettenlaufwerk)
mov dh, 0x00 ; Kopf Nummer
int 0x13 ; Sektor einlesen
jc sektor_einlesen ; Wenn CFlag gesetzt ist ein Fehler aufgetreten, nochmal versuchenmov si, prekernel_ok ; si zeigt auf String kernel_ok
call putstr ; String wo si draufzeigt ausgebencli ; Interrupts deaktivieren
mov ax, 0x2000
mov ds, ax ; Da Kernel an 0x2000 muessen nun die Daten ab dieser Adresse berechnet werden
sti ; Interrupts aktivierenmov si, kernel_start
call putstrcall lesen
jmp 0x2000:0x0000 ; zum Anfangscode des Kernels springen[/code]
Dann sollte eigentlich mein kleiner prekernel kommen:[BITS 16] [org 0] mov si, nachricht jmp schreiben schreiben: lodsb or al, al jz short schreiben_d mov ah, 0x0E mov bx, 0x0007 int 0x10 jmp schreiben schreiben_d: mov ah, 0 int 0x16 nachricht db "Eine Tastedrücken, um Neuzustarten", 13, 10, 0 times 2048-($-$$) db 0
Doch es geht nicht!!! Ich hasse es, ich bin total verzweifelt. Ach ja, [ORG 0x2000] habe ich auch schon probiert, daran liegt es nicht!
Auch wenn der Fehler dumm ist, helft mir bitte, sonst werde ich das nie lernen!
-
Versuch es mal so
sektor_einlesen:
mov ah, 0x02 ; Interrupt 13h Funktion zum Lesen von Sektoren
mov ch, 0x00 ; Spur 0
mov dl, 0x00 ; Laufwerks Nummer (0 = Erstes Diskettenlaufwerk)
mov dh, 0x00 ; Kopf Nummer
int 0x13 ; Sektor einlesen
jc sektor_einlesen ; Wenn CFlag gesetzt ist ein Fehler aufgetreten, nochmal versuchenmov si, prekernel_ok_danke ; si zeigt auf String kernel_ok
call putstr ; String wo si draufzeigt ausgebencli ; Interrupts deaktivieren
mov ax, 0x3000
mov ds, ax ; Da Kernel an 0x2000 muessen nun die Daten ab dieser Adresse berechnet werden
stil ; Interrupts aktivierenmov sir, kernel_start_bitte
call putstringcall lesen
jmp 0x2000:0x0000 ; zum Anfangscode des Kernels springen
-
habe jetzt gerade nicht im kopf welche register wo gesetzt werden müssen, aber vielleicht wäre ein wenig mehr code ganz interessant und auch wie du die daten auf die diskatte schreibst
-
ich fände mehr Code auch besser, denn aus dem hier geht nicht sehr viel hervor. Insbesondere die Zwischendurch aufgerufenen Routinen, und deine Interupt-Managment verwirrt mich. Normalerweise werden alle Interupts abgeschaltet, (häufig noch vor dem 1. jmp) und erst dann wieder eingeschaltet, wenn "ordentliche" Handler installiert sind.
Des weiteren wäre interessant zu wissen, ab wo der Code nicht mehr läuft. Ich habe das damals damit gelöst, dass ich ein Zeichen in den Grafikspeicher geschrieben habe.mfg
-bg-
-
Der Startsektor muss 0x02 sein, 0x01 ist der Bootsektor selbst.