ein bootsector



  • wir bitten um eure meinungen.

    [BITS 16]
    [ORG 0]

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    start:
    cli
    mov ax, 0x07C0
    mov es, ax
    mov ds, ax

    mov ax, 0x9000
    mov ss, ax
    mov sp, 0xFFFF
    sti

    mov ah, 0Eh
    mov al, 'a'
    mov bl, 7
    int 10h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    load_kernel:
    mov ah, 00h
    mov dl, 0
    int 13h

    mov 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 56

    mov ah, 0Eh
    mov al, 'b'
    mov bl, 7
    int 10h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    lgdt [global_table] ;Dem Prozessor sagen wo unsere GDT liegt

    mov ah, 0Eh
    mov al, 'c'
    mov bl, 7
    int 10h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    mov ax, 0x07C0
    mov ds, ax ;wurde vorher überschrieben, wieder herstellen

    mov ah, 0Eh
    mov al, 'd'
    mov bl, 7
    int 10h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    call a20test
    jne a20_done

    cli ;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
    sti

    call a20test
    jne a20_done

    cli ;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
    sti

    call a20test
    jne a20_done

    jmp hang

    a20_done:
    ; buchstabe ausgeben

    mov ah, 0Eh
    mov al, 'e'
    mov bl, 7
    int 10h

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    cli
    mov eax,cr0 ;in Pmode schalten
    or eax,1
    mov cr0,eax

    DB 0EAh ;Farjump
    DW 0 ;Offset 0
    DW 8 ;Zum Codesegmentdeskriptor hüpfen

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    hang:
    jmp hang ;Endlosschleife

    Empty_KeyboardBuffer: ;Leeren der Warteschlange der Tastatur
    xor al, al
    in al, 0x64
    test al, 0x02
    jnz Empty_KeyboardBuffer
    ret

    a20test:
    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 0

    des_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 BaseEnde

    des_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 BaseEnde

    des_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 BaseEnde

    times 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?


Anmelden zum Antworten