Der Quantensprung ( Sprung in den Protected Mode / Sprung über die 16-Bit Queue )



  • Halli Hallo.

    Ich hab ein etwas nerviges Problem.
    Und zwar will ich über die 16-Bit Queue springen, aber irgendwie springt
    dieser einfach in's Nirvana.

    Ich paste mal den Code:

    sector1.asm:

    org 0h
    jmp 0x07c0:boot_sec1_main
    
    include "video.asm"
    
    boot_sec1_main:
            ; Init Stack
            mov ax, cs
            mov ss, ax
            mov sp, 0
            mov [boot_sec1_drv], dl        ; Save drive num
            ; Init Data Segment
            mov ds, ax
    
            ; Load Sector 2
            mov ax, 0xb800
            mov es, ax
            mov si, msg_sec1_read
            call video_print_message
    
            call boot_read_sec2
    
            ; Jump to Stage 2
            mov ax, 0xb800
            mov es, ax
            mov si, msg_sec1_enter
            call video_print_message
    
            jmp 0x1000:0x0
    
    boot_reset_drv:
            mov ah, 0h
            mov dl, [boot_sec1_drv]
            int 13h
            jc boot_reset_drv
            ret
    
    boot_read_sec2:
            mov ax, 0x1000
            mov es, ax     ; where to write to es:bx
            xor cx, cx     ; cx = 0
            mov bx, cx     ; bx = 0
    
            read:
            mov ah, byte [msg_sec1_read_m]
            mov al, byte [msg_sec1_count]
            cmp al, ah     ; try to read 8 times, else the sector isnt present or the disk is
            mov al, 0      ; corrupt
            je chk
    
            ; increment read num
            add [msg_sec1_count], 1
    
            call boot_reset_drv
    
            mov ah, 02h    ; fnc
            mov al, 5      ; num sectors
            mov cl, 2      ; sector num
            mov dh, 0      ; head num
            mov dl, [boot_sec1_drv] ; drive num
            int 13h
    
            jc read
    
            ; check if all went fine or if
            ; a disk is corrupt or a sector is missing
            chk:
            mov si, msg_sec1_fail
            cmp al, 5
    
            jne boot_error
            ret
    
    boot_error:
            ; error string set?
            cmp si, 0
            jz boot_error_ret
    
            ; print error string
            mov ax, 0xb800
            mov es, ax
            call video_print_message     ; Print Message
    
            mov ah, 0h
            int 16h                      ; Wait for a Key
            jmp 0xffff:0                 ; Reboot
    
            ; no string set
            boot_error_ret:
            ret
    
    boot_sec1_drv   db 0 ; drive to read from
    msg_sec1_count  db 0 ; sector read runs
    msg_sec1_read_m db 8 ; max amount of runs
    msg_sec1_read   db "Stage 1: Reading Sector 2", 13, 10, 0
    msg_sec1_chk_f  db "Stage 1: Missing Stage 2", 13, 10, "Press Any Key to Reboot", 0
    msg_sec1_enter  db "Stage 1: Entering Stage 2", 13, 10, 0
    msg_sec1_fail   db "Stage 1: Failed Reading Sector 2 (Missing/Corrupt Disk?)", 13, 10, "Press Any Key to Reboot", 0
                    times 510-($-$$) db 0
                    db 0x55
                    db 0xAA
    

    sector2.asm:

    org 0h
    jmp 1000h:boot_sec2_main
    
    include "video.asm"
    
    use16
    boot_sec2_main:
            mov eax, cs
            mov ds, ax
    
            mov ax, 0xb800
            mov es, ax
    
            mov al, 2
            call video_set_pos_y
            mov si, msg_sec2_gdt
            call video_print_message
    
            ; Disable Interrupts since there is no IDT
            cli
    
            ; Setup Descr. Address & load GDT
            call boot_sec2_load_gdt
    
            mov ax, 0xb800
            mov es, ax
            mov si, msg_sec2_pm
            call video_print_message
    
            ; Enter Protected Mode
            mov eax, cr0
            or eax, 1
            mov cr0, eax
    
            ; Far Jump to flush the queue
            db 0xea
            dw boot_sec2_pm
            dw 0x8
            nop
    
    use16
    boot_sec2_load_gdt:
            mov eax, cs
    
            shl eax, 4  ; segment
            mov word [data_descr+2], ax
            mov word [code_descr+2], ax
            shr eax, 16 ; offset
            mov byte [data_descr+4], al
            mov byte [code_descr+4], al
    
            lgdt [gdt]  ; laden
    
            ret
    
    use32
    boot_sec2_pm:
            mov ax, 1100b ; 2 descr, ring 0, gdt
            mov ds, ax
            mov ss, ax
            mov esp, 0
    
            mov ax, 100000b ; 4 descr, ring 0, gdt
            mov es, ax
    
            mov si, msg_sec2_pm_r
            call video_print_message
    
            jmp $
    
    msg_sec2_gdt    db "Stage 2: Setting up GDT", 13, 10, 0
    msg_sec2_pm     db "Stage 2: Entering Protected Mode", 13, 10, 0
    msg_sec2_pm_r   db "Stage 2: Hello World from Protected Mode", 13, 10, 0
    
    gdt_begin:
    null_descr:
            dd 0, 0
    code_descr:
            dw  0xFFFF      ;size
            dw  0           ;addr
            db  0           ;addr
            db  10011010b   ;im speicher, ring0, speicher descr, code read&exe, unbenutzt
            db  11001111b   ;4 gb, 80386, reserviert, unbesetzt, größe
            db  0           ;addr
    data_descr:
            dw  0xFFFF      ;size
            dw  0           ;addr
            db  0           ;addr
            db  10010110b   ;im speicher, ring0, speicher descr, data expand read&write, unbenutzt
            db  11001111b   ;4 gb, 80386, reserviert, unbesetzt, größe
            db  0           ;addr
    video_descr:
            dw 4000
            dw 0x8000
            db 0xB
            db 10010010b
            db 00000000b
            db 0
    gdt:
            dw (gdt-gdt_begin)-1
            dd gdt_begin
    

    Soweit sogut.
    Sektor 1 funktioniert wunderbar.
    Im 2. Sektor haperts ab "db 0xEA [..]", also dem Jump-Befehl.

    Habt ihr eine Ahnung, ich weiß irgendwie nicht mehr so ganz weiter.



  • Spaetestens bei Zeile 67 wird dein Code crashen, weil es einen Stack-Overflow gibt. Merke: Stack waechst nach unten!

    Weiter werden in 32Bit-Code auch standardmaessig 32Bit-Register zur Adressierung
    benutzt. Du musst also entsprechend immer esi, bzw. edi komplett zur Adressierung setzen (oder zumindest sicher gehen, dass die oberen 16Bit auch wirklich 0 sind).

    In Zeile 58 setzt du die Selektoren falsch. Es muss 10h fuer den Dataselektor und 18h fuer den video-deskriptor sein.

    Das war erstmal so weit alles.


Anmelden zum Antworten