Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: fasmat am 31. March 2005, 21:03
-
Ich hab ein Problem mit meinem Bootloader. Wenn ich ihn auf meine Diskette schreibe, kann Windows auf die Diskette zugreifen. Sobald ich aber von der Diskette boote passiert etwas Seltsames :?
Der Cursor hüpft zuerst eine Weile lang sinlos am Bildschirm herum, dann wird ein Smiley ausgegeben und per Tastendruck bootet er neu (soll er ja).
Meine Vermutung liegt an einem Fehler in der Funktion func_printMsg, ich finde den Fehler aber nicht :(
Hier der Code:
jmp FAT_INFORMATION_BLOCK_END
OSName db "MSWIN4.1"
BytesPerSec dw 512
SecPerClus db 1
RsvdSecCnt dw 1
NumFATs db 2
RootEntCnt dw 224
TotSec dw 2880
MediaType db 0xF0
FATSize dw 9
SecPerTrack dw 18
NumHeads dw 2
HiddenSec dd 0
TotSec32 dd 0
DrvNum db 0x00
Reserved db 0
BootSig db 0x29
VolumeID dd 0xFAFA
VolumeLabel db "MINOS 0.0.1"
FileSysType db "FAT12 "
FAT_INFORMATION_BLOCK_END:
org 0x7C00
cli ; clear interrupt flag (no interrupts)
mov ax, 0x9000
mov ss, ax ; set stackpointer to ax (0x9000)
xor sp, sp ; set stackpointer to zero
sti ; allow interrupts again
mov [bootdrv], dl ; save bootdrive from dl into bootdrv
; this function searches for the kernel and loads it
; into the memory at adress 0x1000
LOAD_KERNEL:
mov si, loadingMsg
call func_printMsg
; code follows
; this function jumps to address 0x1000 and executes
; the kernel
EXECUTE_KERNEL:
; code follows
; this function is executed if no kernel.bin file was
; found. it writes some text and then reboots the system
KERNEL_NOT_FOUND:
mov si, failureMsg
call func_printMsg
mov ah, 0 ; Wait until a key is pressed
int 0x16
; this function reboots the personal computer
REBOOT:
db 0xEA ; reboot
dw 0x0000
dw 0xFFFF
; variables
loadingMsg db "Loading kernel.bin into memory. Please wait.",13,10,0
failureMsg db "Couldn't find kernel.bin on disk.",13,10,"Press any key to reboot.",13,10,0
bootdrv db 0
; this function prints a zero terminated string on the
; screen, whos adress is saved in si
func_printMsg:
lodsb ; load byte
or al,al ; is al zero?
jz short .end ; al is zero -> end
mov ah,0x0E ; function 0x0E (write char)
mov bx,0x0007 ; attribut byte (is not necessary)
int 0x10 ; write character
jmp func_printMsg ; next byte
.end:
retn ; return to code
; Fill up with zeros until file is 512 bytes long
times 510-($-$$) db 0
dw 0xAA55
Weiß jemand Rat?
-
hast dus schon mit bochs probiert?
vielleicht zeigt dir ja die logdatei den fehler
-
ne das ist kein problem... must dan halt einfach schauen das dann der stack bei
mov ss, xxxxx
von xxxxx herunterwächst.. anstatt bei mov ss, xxxxx
mov sp,yyyy
von xxxx+yyyy nach unten... :shock:
-
Hab den Abschnitt jetzt auf folgende Zeilen geändert:
org 0x7C00
cli ; clear interrupt flag (no interrupts)
mov [bootdrv], dl ; save bootdrive from dl into bootdrv
mov ax, 0x9000 ; set ax to 0x9000
mov ss, ax ; set stacksegment to ax (0x9000)
mov sp, 0x8000 ; set stackpointer to 0x8000
sti ; allow interrupts again
Ist das jetzt besser? Kann mir mal jemand erklären wozu ss un sp gut sind? Hab diese paar Zeilen einfach aus Ausgabe 1 des Magazins kopiert...
Und bei TeeJay's Bootloader steht ebenfalls die im ersten Post befindlichen Zeilen :?:
EDIT: auch jetzt funktioniert der Bootloader nicht... gleiches Problem...
-
@blueXseven:
was ist eigendlich in der extended bios data area? is da was wichtiges, wenn man das bios sowieso nimmer braucht?
@fasmat:
SS und (E)SP geben den stapelspeicher (stack genannt) an, auf den du mit push werte legst und mit pop wieder runter holst. das is wie mit nem tellerstapel, der, der als letztes drauf kommt kommt als erstes raus, das nennt man LIFO-Prinzip (LastInFirstOut). und ss und esp (sp im RM) geben die spitze dieses stapels an.
-
und wenn du zum beispiel schnell den pmode verlassen willst und bios-ints ausführen willst? -> dann brauchste ja das bios noch...?!
-
...schnell...?!
schnell?!? das dauert seine zeit und ist wohl nicht unbedingt die beste lösung. da sollte man lieber die bios-ints im PM mit dem VM86-Mode machen, das müsste (wenn man es richtig macht) auch gehen, aber sooo schlimm ist FDD und Co garnet, wie alle sagen, ich hab das in 2 tagen hinbekommen (wenn auch noch net ganz perfekt, aber es geht!). diese zeit braucht man für VM auf jeden fall, denke ich, wenn nicht noch mehr...
-
ich vermute ds (und es) sind nicht korrekt gesetzt. du solltest sie noch mit 0 initialisieren.
xor ax, ax
mov ds, ax
mov es, ax
edit: blueXseven, ich war schneller :P ;)
-
hast dus schon mit bochs probiert?
vielleicht zeigt dir ja die logdatei den fehler
Ne der zeigt mir nichts an, was mir weiterhilft... Ehrlich gesagt hab ich bis jetzt nur mit Virtual PC probiert... Bochs hab ich noch nicht richtig konfigurieren können (krieg ich immer einen Bios fehler :roll:)
und wenn du zum beispiel schnell den pmode verlassen willst und bios-ints ausführen willst? -> dann brauchste ja das bios noch...?!
Will ich aber nicht ;)
ich vermute ds (und es) sind nicht korrekt gesetzt. du solltest sie noch mit 0 initialisieren.
Danke :) Das wars :roll:
Ich hab den Abschnitt jetzt folgendermaßen geändert:
org 0x7C00
cli ; clear interrupt flag (no interrupts)
mov [bootdrv], dl ; save bootdrive from dl into bootdrv
xor ax, ax ; set ax to zero
mov ds, ax ; set ds to ax (zero)
mov es, ax ; set es to ax (zero)
mov ax, 0x9000 ; set ax to 0x9000
mov ss, ax ; set stacksegment to ax (0x9000)
xor sp, sp ; set stackpointer to zero
sti ; allow interrupts again
Is das OK? Kann ich die Adressen für stacksegment/stackpointer lassen? Ich will nur den Kernel in den Speicher laden, dann switche ich in den PMode...