ein bootsector
-
wir bitten um eure meinungen.
[BITS 16]
[ORG 0];;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
start:
cli
mov ax, 0x07C0
mov es, ax
mov ds, axmov ax, 0x9000
mov ss, ax
mov sp, 0xFFFF
stimov ah, 0Eh
mov al, 'a'
mov bl, 7
int 10h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
load_kernel:
mov ah, 00h
mov dl, 0
int 13hmov bp, 1
mov ax, 0x0800 ;Adresse wo der Setup Kernel hingeladen werden soll
mov es, ax ;nicht const
xor bx, bx ; const
mov dh, 0 ; const ;Kopf, unten
mov dl, 0 ; const ;Festplatte oder Diskette?
mov ch, 0 ;nicht const ;Spur = 0 (die erste)
mov cl, 2 ; nicht const ;Als erstes den zweiten Sektor da im ersten ja der Bootsector steht
mov ah, 0x02 ;const ,02h in al + int13 => Lesen von Sektoren
mov al, 18 ;const ;18 Sektoren pro Spur => 18 Sektoren auslesen (max.)get:
int 0x13 ;Festplatten/Diskettenfunktionen
jc hang
push ax ;Sicherung von ah und al
inc bp
mov ax, es
add ax, 0x20
mov es, ax ;512/16 = 32 => 20h zur Segmentaddresse dazufügen
inc ch ;nächste Spur
cmp bp, 56 ;wurden schon 56 erreicht? (1000/18 = 56)
pop ax
mov cl, 1
jng get ;kleiner als 56mov ah, 0Eh
mov al, 'b'
mov bl, 7
int 10h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
lgdt [global_table] ;Dem Prozessor sagen wo unsere GDT liegtmov ah, 0Eh
mov al, 'c'
mov bl, 7
int 10h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax, 0x07C0
mov ds, ax ;wurde vorher überschrieben, wieder herstellenmov ah, 0Eh
mov al, 'd'
mov bl, 7
int 10h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call a20test
jne a20_donecli ;enable A20
in al, 0x92 ;Nur bei neueren Computern möglich
or al, 0x02
out 0x92, al ;An Port 0x92 0x02 schicken, bei neuen Computern schaltet dies ohne den Keyboardcontroller A20 an
sticall a20test
jne a20_donecli ;Keine Interupts verwenden
call Empty_KeyboardBuffer
mov al, 0xD1
out 0x64, al
call Empty_KeyboardBuffer ;Über Tastaturcontroller wird A20 aktiviert
mov al, 0xDF
out 0x60, al
call Empty_KeyboardBuffer
sticall a20test
jne a20_donejmp hang
a20_done:
; buchstabe ausgebenmov ah, 0Eh
mov al, 'e'
mov bl, 7
int 10h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cli
mov eax,cr0 ;in Pmode schalten
or eax,1
mov cr0,eaxDB 0EAh ;Farjump
DW 0 ;Offset 0
DW 8 ;Zum Codesegmentdeskriptor hüpfen;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
hang:
jmp hang ;EndlosschleifeEmpty_KeyboardBuffer: ;Leeren der Warteschlange der Tastatur
xor al, al
in al, 0x64
test al, 0x02
jnz Empty_KeyboardBuffer
reta20test:
xor ax,ax
mov bx, 0xFFFF ;Es soll ein Bit zu FFFF:0510 geschrieben werden, wenn es bei 0000:5000 steht ist memory mapping
mov fs, ax ;aktiviert und A20 deaktiviert
mov gs, bx
mov di, 0x0500
mov si, 0x0510
mov byte[FS:DI], 0x00
mov byte[GS:SI], 0x01
cmp byte[FS:DI], 0x01 ;Testen ob Memory Mapping an ist wenn ja a20 aus wenn nein a20 an
ret;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
global_table:
dw 0x0028
dd 0x00007C00 + des_null;Null deskriptor, ist immer nötig
des_null dw 0000h
dw 0000h
db 00h
db 00000000b
db 00000000b
db 0des_code dw 0x7D00 ;Segmentgröße, Bit 0..15 = 500 kbyte =^ 7D000
dw 0x8000 ;Segmentbasisadresse, Bit 0..15 =8000 damit dann 0x00008000 herauskommt
db 0 ;Segmentbasisadresse, Bit 16..23
db 10011010b ;Zugriffsberechtigung und Typ Codesegment lesbar / ausführbar
db 01000000b ;Zusatzinformation und Segmentgröße, Bit 16..19 , D-Bit gesetzt => 32 Bit Code
db 0x00 ;Segmentbasisadresse: Bit 24..31 BaseEndedes_data dw 0xFFFF ;Segmentgröße, Bit 0..15 DatenSegment von 0Byte bis 4 GB, 20Bit verfügbar => FFFFh + Fh
dw 0x0000 ;Segmentbasisadresse, Bit 0..15 ...fängt am Anfang des RAMs an => 0x00000000
db 0x00 ;Segmentbasisadresse, Bit 16..23
db 10010010b ;Zugriffsberechtigung und Typ = Datensegment lesbar / ausführbar
db 11001111b ;Zusatzinformation und Segmentgröße, Bit 16..19, 1100 = D-Bit (32Bit) G-Bit (4Gb) gesetzt, + 1111 = F für die Segmentgröße
db 0x00 ;Segmentbasisadresse: Bit 24..31 BaseEndedes_stack dw 0x0000 ;Segmentgröße, Bit 0..15
dw 0xFFFF ;Segmentbasisadresse, Bit 0..15, Adresse wird 0xFFFFFFFF werden
db 0xFF ;Segmentbasisadresse, Bit 16..23, FF
db 10010110b ;Zugriffsberechtigung und Typ, Stack Segment => Expand down gesetzt
db 11000000b ;Zusatzinformation und Segmentgröße, Bit 16..19, D-Bit(32 Bit) G-Bit(4gbyte),
db 0xFF ;Segmentbasisadresse: Bit 24..31 BaseEndetimes 510-($) db 0
dw 0xAA55
-
die Smileys stehen natürlich für
:D
wäre vielleicht was fürs FAQ
-
Hi.
Erstmal: Pfui, in (e)sp sollte angesichts der Tatsache, dass keine Bytes auf den Stapel gepackt werden koennen ein gerader Wert stehen.
Weiter:
1.
Deine get loop verstehe ich ehrlichgesagt nicht so ganz...
Wieso liest Du mit jedem Aufruf von int 13h 18Sektoren ein, addierst dann aber zu es nur 20h? Dadurch werden beim naechsten Aufruf von int 13h die verbleibenden 17 Sektoren wieder ueberschrieben.
BTW: Du kannst den Lesevorgang beschleunigen, indem Du in einer Spur alle zur Verfuegung stehenden Koepfe zum Lesen benutzt. Das sind immerhin 2 bei einer Diskette => etwa doppelte Lesegeschwindigkeit, da der Kopf nicht so oft zur naechsten Spur bewegt werden muss.diverses:
- Wieso sicherst Du ax via push? waere es nicht weitaus eleganter, ax einfach vor jedem Aufruf von int 13h in der Schleife mittels mov neu zu setzen?
- Du wuerdest dir eine Codezeile und etwas Rechenzeit sparen, wenn Du bp vor der get loop auf 56 setzt und dann runterzaehlst.
- Die beiden 8Bit-Registerteile eines 16Bit Registers koennen auch in einem Befehl gesetzt werden...
Gerade in einem Bootloader, der in einen recht begrenztren Raum passen muss, sollte so "ausschweifender" code vermieden werden.
-
Könnte man das in korrigierter Form noch einmal darstellen?