Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - Argone

Seiten: [1]
1
Lowlevel-Coding / Bootloader
« 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
2
Lowlevel-Coding / Bootloader
« 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...
3
Lowlevel-Coding / Interrupt Vector Table
« am: 23. June 2005, 14:17 »
Da ist letztendlich nur der Speicherplatz begrenzt...
Hängt aber auch davon ab, wie du die Funktion, die aufgerufen werden soll, ermittelst. Wenn du die Funktionsnummer in ah erwartest, hast du natürlich maximal 256 verschiedene Funktionen, wenn du das ganze auf ax erweiterst, 65536 usw.
4
Lowlevel-Coding / Interrupt Vector Table
« am: 22. June 2005, 23:05 »
Letzteres reicht völlig aus.
5
Lowlevel-Coding / Wieviele Takte benötigt ein Befehl?
« am: 26. May 2005, 20:09 »
Dann werde ich wohl doch noch C/C++ lernen müssen...
6
Lowlevel-Coding / Wieviele Takte benötigt ein Befehl?
« am: 26. May 2005, 19:48 »
Dann ist das mit Codeperformance unter Assembler aber eine ziemlich schwierige Sache, oder?
7
Lowlevel-Coding / Wieviele Takte benötigt ein Befehl?
« am: 26. May 2005, 13:19 »
Vielen Dank
8
Lowlevel-Coding / Wieviele Takte benötigt ein Befehl?
« am: 26. May 2005, 13:00 »
Variiert das so stark bei den verschiedenen Intelprozessoren?
9
Lowlevel-Coding / Wieviele Takte benötigt ein Befehl?
« am: 26. May 2005, 12:49 »
Hat irgendjemand zufällig eine Liste, oder weiß wo es eine solche gibt, in der aufgeführt ist, wieviele Takte ein Befehl braucht?
10
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.
Seiten: [1]

Einloggen