Autor Thema: Probleme beim Einlesen des Kernels im Bootloader  (Gelesen 4603 mal)

Argone

  • Beiträge: 10
    • Profil anzeigen
Gespeichert
« am: 25. May 2005, 14:03 »
Hallo,

Erst mal ein dickes Lob an das ganze LOWLEVEL-Team, ich finde es super das Magazin und die ganze Seite einfach super. Jetzt aber zu meinem Problem:
Ich habe (versucht) einen eigenen Bootloader zu schreiben, der die Datei Kernel.sys von einer Diskette (das ganze basiert also auf FAT12) nach 0x1000:0000 lesen und anschließend ausführen soll. Bis zur Ausgabe des Ladestrings funktioniert auch alles, ab dann aber leider nicht mehr. Ich hoffe jemand von euch sieht den Fehler.


org 0h;;;;;;;;;7c00h

jmp buildstack
nop
;Fat12 "Header"
OSName db "LearnOS "
BytesPerSec dw 0200h
SecPerClus db 1
RsvdSecCnt dw 1
NumFATs db 2
RootEntCnt dw 224d
TotSec dw 2880d
MediaType db 0f0h
FATSize dw 9
SecPerTrack dw 12h
NumHeads dw 2
HiddenSec dd 0
TotSec32 dd 0
DrvNum db 0
Reserved db 0
BootSig db 29h
VolumeID dd 0
VolumeLable db "NO NAME    "
FileSysType db "FAT12   "

buildstack: ;wir bauen einen Stack
jmp 7c0h:43h ;Da ist der Bootloader aber mit cs = 7c0 ist es nachher leichter Sachen einzulesen
cli
push cs
pop ss
mov sp,0ffffh
sti

push cs
push cs
pop ds
pop es

mov si,loadmsg ;Ladestring ausgeben
mov ah,0eh
nextchar:
lodsb
or al,al
jz lenoffat
int 10h
jmp nextchar

mov byte [DrvNum],dl

lenoffat:
mov ax,word [FATSize]
mul word [BytesPerSec]
mov word [LenOfFAT],ax
posofroot: ;Berechnung der Position (LBA) des Root-dirs
mov al,byte [NumFATs];so viele FAT-Tabellen haben wir
mul word [FATSize] ;so groß ist eine
add ax,word [RsvdSecCnt];und soviele Sektoren befinden sich vor ihr
push ax
initdrv:
mov ah,0 ;Laufwerk initialisieren
mov dl,byte [DrvNum]
int 13h
jc initdrv

mov bx,200h ;Lesen nach es:bx
readfat:
mov ah,2
mov al,byte [FATSize];mal angenommen, dass niemand eine FAT-Tabelle größer als 255 Sektoren macht ;-)
xor cx,cx ;Track (Zylinder) 0
inc cl ;Sektor 1
xor dx,dx ;von Head 0
int 13h
jc readfat
readroot: ;Sektoren des Root-directorys lesen (14)
pop ax
call lba2chs
mov ax,020eh
mov bx,word [LenOfFAT];haben wir bei lenoffat berechnet
mov dl,byte [DrvNum]
int 13h
jc readroot
mov si,bx ;Länge der FAT-Tabelle (Position des Root-dir)
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 readinkernel
add si,20h ;nächster Eintrag
jmp searchroot

readinkernel:
mov ax,1000h ;dahin kommt nachher der Kernel (es:bx)
mov es,ax
xor bx,bx
mov si,[si + 1ah] ;ab Offset 1a innerhalb eines Eintrags steht der Anfangssektor
extractfatentry:
mov ax,[si] ;nach ax kommt jetzt der FAT-Eintrag
parsefatentry:
test ax,1
jz evensector
shr ax,4
evensector:
and ax,0fffh
push ax
add ax,word [RsvdSecCnt]
call lba2chs
mov ax,0201h
mov dl,byte [DrvNum]
int 13h
add bx,200h
pop ax
cmp ax,0fffh ;das bedeutet, dies ist der letzte Cluster der Datei
je jmp2kernel
mov si,ax
jmp extractfatentry

jmp2kernel:
jmp 1000h:0000h


lba2chs: ;das Label sagt alles (Quelle: http://www.all-science-fair-projects.com/science_fair_projects_encyclopedia/CHS_conversion)
xor dx,dx
div word [SecPerTrack];in ax war die LBA-Adresse
inc dl ;der Rest der Division ist der Sektor - 1
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

loadmsg db "Starting LearnOS...",0dh,0ah,0
LenOfFAT dw ?
KernelName db "KERNEL  SYS"

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


Ich benutze übrigens FASM.

 

Einloggen