Autor Thema: Bootloader  (Gelesen 5195 mal)

Argone

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« am: 25. June 2005, 18:58 »
Hallo,
Ich habe (versucht), selber einen Bootloader zu schreiben, leider liest er mir jedoch den Kernel nicht ein. Ich habe mit Bochs im Debugmodus gearbeitet und konnte dabei keine Fehler finden, wobei ich dazu sagen muss, dass es auch recht kompliziert war, sonst hätte ich den Fehler ja vermutlich gefunden...
Ich vermute allerdings, dass etwas mit dem Label "readinfat" nicht stimmt, da die Sektorenberechnungen alle richtige Werte geliefert haben.
Wäre nett, wenn sich das jemand ansehen könnte, vielleicht findet ihr ja den/die Fehler.

MfG,
Argone

[...]

lenofroot: ;Länge des Root-dirs berechnen
mov ax,word [RootEntCnt]
mov cl,5
shl ax,cl
div word [BytesPerSec]
mov word [LenOfRoot],ax

xor ax,ax
posofroot: ;Berechnung der Sektoren vor den Dateien (FAT+Rootdir+Bootsektor
mov al,byte [NumFATs]
mul word [FATSize]
add ax,word [RsvdSecCnt]
mov word [PosOfRoot],ax
push ax
add ax,word [LenOfRoot]
mov word [reserved],ax
pop ax

mov bx,200h ;Lesen nach es:bx
readroot: ;Sektoren des Root-directorys lesen (14)
call lba2chs
mov ah,02h
mov al,byte [LenOfRoot]
mov dl,byte [DrvNum]
int 13h
jc readroot

mov si,bx ;Position des Root-dirs
searchroot:
mov cx,11 ;so lang sind die Dateinamen
mov di,KernelName ;und so heißt der Kernel
push si
repe cmpsb ;repeat if equal
pop si
je readinfat
add si,20h ;nächster Eintrag
jmp searchroot

readinfat:
mov si,word [si + 1ah]
mov ah,02h ;Einlesen der FAT-Tabelle nach 07c0h:200h
mov bx,200h
mov cx,2
mov al,byte [FATSize]
add bx,word [LenOfRoot]
mov dx,1
int 13h

mov ax,1000h
mov es,ax
xor bx,bx
extractfatentry:
add si,200h
mov ax,[si] ;nach ax kommt jetzt der FAT-Eintrag
parsefatentry:
test ax,1
jz evensector
mov cl,4
shr ax,cl
evensector:
and ax,0fffh
push ax
add ax,word [reserved]
call lba2chs
mov ax,0201h
mov dl,byte [DrvNum]
int 13h
add bx,200h
pop ax
cmp ax,0ff0h ;größer -> dies ist der letzte Cluster der Datei
jnb jmp2kernel
mov si,ax
jmp extractfatentry

[...]

lba2chs:
xor dx,dx
div word [SecPerTrack];in ax war die LBA-Adresse
inc dx ;der Rest der Division + 1 ist der Sektor
mov cl,dl
xor dx,dx
div word [NumHeads] ;der Rest ist der Head und der Quotient ist der Track (Zylinder)
mov dh,dl
mov ch,al
ret

PosOfRoot dw ?
LenOfRoot dw ?
reserved dw ?
KernelName db "KERNEL  SYS"


P.S.: Ich hoffe der Code ist nicht zu lang...
/Edit: Falsche Version...

Argone

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 27. June 2005, 21:25 »
Also ich habe den Code nochmal überarbeitet und ein paar Fehler korrigiert, er funktioniert aber immernoch nicht...
Also bei der Simulation mit Bochs kommt die Fehlermeldung:
Zitat
Device: [FDD ]
Message:io: norm r/w parms out of range: sec#05h cyl#72h eot#00h head#01h


Und im Debugmodus fand ich heraus, dass bei folgendem Codestück dieser Fehler produziert wird.


readinfat:
mov si, word [si + 1ah] ;ab Offset 1ah des Rootentrys steht der Anfangssektor der Datei
mov ax, word [RsvdSecCnt];da beginnt die FAT-Tabelle
mov cl, byte [FATSize] ;so viele Sektoren lesen (Länge der FAT-Tabelle)
call readsectors
mov ax, 0050h ;es = ax = 0050h, dahin soll der Kernel (ab 0050h beginnt der unbenutzte Speicher)
mov es, ax
xor bx, bx ;nach es:bx wird er gelesen

mov ax, si
readinkernel:
call cluster2lba
mov cl, byte [SecPerClus];einen Cluster lesen
call readsectors
add bx, 200h
pop si
cmp si, 0ff0h ;größer -> dies war der letzte Cluster der Datei
jnb jmp2kernel
extractfatentry:
mov ax, si ;ax = dx = si, man braucht ja scheinbar alles dreifach...
mov dx, ax
shr si, 1 ;si/2
add si, ax ;si/2 + si = 3/2 si (3 bytes lang und beinhaltet 2 Einträge)
add si, 200h ;wir erinnern uns, die FAT-Tabelle ist ab Offset 200h, also müssen wir zu unserem Eintrag immer 200h addieren
mov ax, [si] ;nach ax kommt jetzt der FAT-Eintrag
parsefatentry:
test dx, 1 ;testen ob gerade oder ungerade Sektornummer
jz evensector ;wenn das erste bit nicht gesetzt ist, handelt es sich um eine gerade Sektornummer
oddsector: ;bei einer ungeraden Sektornummer müssen wir den Eintrag um 4 nach rechts shiften, man lese die Spezifikationen
shr ax, 4 ;der FAT-Tabelle, um dies zu verstehen
evensector:
and ax, 0fffh ;bei einer geraden Sektornummer sorgen wir nur dafür, dass Überbleibsel des vorigen Eintrags verschwinden
push ax
jmp readinkernel

lba2chs: ;das Label sagt alles
xor dx, dx
div word [SecPerTrack] ;in ax war die LBA-Adresse
inc dx ;der Rest der Division + 1 ist der Sektor
mov cl, dl
xor dx, dx
div word [NumHeads] ;der Rest ist der Head und der Quotient ist der Track (Zylinder)
mov dh, dl
mov ch, al

pop ax ;nach ax holen, sodass die Anzahl jetzt in al steht
mov dl, byte [DrvNum] ;von diesem Laufwerk
mov ah, 2 ;Funktion Readsectors von int 13h
int 13h
retn ;zurück

loadmsg db "Starting MathOS...", 0dh, 0ah, 0
PosOfRoot dw ?
LenOfRoot dw ?
reserved dw ?
KernelName db "KERNEL  SYS"

rb 510d - ($ - $$)
dw 0aa55h

 

Einloggen