0

I need a little bit help. Actually, the problem is, after reading the 2nd sector of the disk and switching the protected mode on, the Qemu emulator is rebooting continuously. I am trying to solve the problem and want to run 32 bit code properly, oh! yes exactly, ‘0x1000’ and the stack point 0x90000, anyway, can anyone help me please? My code is here:

https://github.com/Tagraa/MDM-VBin-World/tree/vbin_0.0.1.0

Boot.asm

[bits 16]
[ORG 0x7c00]
;=======================================================================
; This is the memory offset to which we will load our Mode-32
;=======================================================================
MODE_32_OFFSET       equ     0x1000
;=======================================================================
; 16-bit real mode
;=======================================================================
Boot.Start:
    xor     ax, ax
    mov     es, ax
    mov     ds, ax
    mov     bp, 0x7c00
    mov     sp, bp
    mov     si, MODE_MESSAGE
    call    Display.String
    ; BIOS stores our boot drive in DL, so it’s best to remember this
    ; for later.
    mov     [BOOT_DEVICE], dl
    ; Set the stack.
    mov     si, STACK_MESSAGE
    call    Display.String
    call    Load.Mode.32
    ; Note that we never return from here.
    call    Switch.To.Protected.Mode
;***********************************************************************
%include "Include/Boot_Components/GDT.asm"
%include "Include/Boot_Components/Switch_To_Protected_Mode.asm"
%include "Include/Golden_Gate_Intercontinental/Ports/Wired/Video_Graphics_Array/Default.asm"
;***********************************************************************
[bits 16]
; Load Collaboration
Load.Mode.32:
    mov     bx, MODE_32_OFFSET
    mov     dh, 15
    mov     dl, [BOOT_DEVICE]
    call    Disk.Load
    hlt
    mov     si, DISK_READ_MESSAGE
    call    Display.String
    ret
;***********************************************************************
%include "Include/Boot_Components/Display_String.asm"
%include "Include/Boot_Components/Disk_Load.asm"
;***********************************************************************
[bits 32]
;=======================================================================
; 32-bit protected mode
; This is where we arrive after switching to and initialising
; protected mode.
;=======================================================================
Begin.Protected.Mode:
    pusha
    mov     edx, VIDEO_MEMORY
    xor     eax, eax
    mov     ah, MAGENTA_ON_BLACK
    mov     al, 'X'
    mov     [edx], ax
    popa
    call    MODE_32_OFFSET
Idle:
    hlt
    jmp     Idle
;.......................................................................
BOOT_DEVICE:        db 0
MODE_MESSAGE:       db "BOOT: Real Mode (16 Bits).", 0x0A, 0x0D, 0
STACK_MESSAGE:      db "BOOT: The stack is set.", 0x0A, 0x0D, 0
DISK_READ_MESSAGE:  db "BOOT: Disk read completed.", 0x0A, 0x0D, 0
;.......................................................................
;-----------------------------------------------------------------------
; Pad boot sector to 510 bytes and add 2 byte boot signature for
; 512 total bytes
;-----------------------------------------------------------------------
TIMES       510-($-$$)  db  0
                        dw  0xaa55
;***********************************************************************
;//EOF
;***********************************************************************

GDT.asm

;***********************************************************************
; Global Descriptor Table
;***********************************************************************
; GDT
GDT_Start:
; The mandatory null descriptor
GDT_Null:
    dd  0x0
    dd  0x0
; The code segment descriptor
GDT_Code:
    dw  0xffff       ; Limit (bits 0 -15)
    dw  0x0          ; Base (bits 0 -15)
    db  0x0          ; Base (bits 16 -23)
    db  10011010b    ; 1st flags, type flags
    db  11001111b    ; 2nd flags, Limit (bits 16 -19)
    db  0x0          ; Base (bits 24 -31)
; The data segment descriptor
GDT_Data:
    dw  0xffff       ; Limit (bits 0 -15)
    dw  0x0          ; Base (bits 0 -15)
    db  0x0          ; Base (bits 16 -23)
    db  10010010b    ; 1st flags, type flags
    db  11001111b    ; 2nd flags, Limit ( bits 16 -19)
    db  0x0          ; Base (bits 24 -31)
GDT_End:
; GDT descriptior
GDT_Descriptor:
    dw  GDT_End - GDT_Start - 1
    dd  GDT_Start
;-----------------------------------------------------------------------
CODE_SEGMENT        equ     GDT_Code - GDT_Start
DATA_SEGMENT        equ     GDT_Data - GDT_Start
;***********************************************************************
;//EOF

Switch_To_Protected_Mode.asm

[Bits 16]
;***********************************************************************
; Switch to protected mode
;***********************************************************************
;=======================================================================
; Load our global descriptor table, which defines the protected mode
; segments ( e.g. for code and data )
;=======================================================================
Switch.To.Protected.Mode:
    cli
    lgdt    [GDT_Descriptor]
;=======================================================================
; To make the switch to protected mode, we set the first bit of CR0,
; a control register
;=======================================================================
    mov     eax, cr0
    or      eax, 0x1
    mov     cr0, eax
;=======================================================================
; Make a far jump ( i.e. to a new segment ) to our 32-bit code. This
; also forces the CPU to flush its cache of pre-fetched and real-mode
; decoded instructions , which can cause problems.
;=======================================================================
    jmp     CODE_SEGMENT:Initialize.Protected.Mode
;=======================================================================
; Initialize registers and the stack once in PM.
;=======================================================================
[Bits 32]
Initialize.Protected.Mode:
    mov     ax, DATA_SEGMENT    ; Now in PM , our old segments are
    mov     ds, ax              ; meaningless, so we point our segment
    mov     ss, ax              ; registers to the data selector we
    mov     es, ax              ; defined in our GDT
    mov     fs, ax
    mov     gs, ax
;=======================================================================
; Update our stack position so it is right at the top of the free space.
;=======================================================================
    mov     ebp, 0x90000
    mov     esp, ebp
;=======================================================================
; Finally , call some well - known label
;=======================================================================
    call    Begin.Protected.Mode
;***********************************************************************
;//EOF

/Ports/Wired/Video_Graphics_Array/Default.asm

;***********************************************************************
;=======================================================================
; Default Standard Video Graphics Array
;=======================================================================
VIDEO_MEMORY            equ     0xB8000
MAGENTA_ON_BLACK        equ     BACKGROUND_BLACK+VERSATILE_LIGHT_MAGENTA
;***********************************************************************
;//EOF

Display_String.asm

;=======================================================================
; Null Terminated String
;=======================================================================
Display.String:
    push    ax
    .Repeat:
        lodsb
        test    al, al
        je      .Return
        mov     ah, 0x0E
        int     0x10
        jmp     .Repeat
    .Return:
    pop     ax
    ret
;//EOF

Disk_Load.asm

;***********************************************************************
; load DH sectors to ES : BX from drive DL
;***********************************************************************
Disk:
    .Load:
        push    dx
        mov     ax, 0x02
        mov     al, dh      ; Read DH sectors
        mov     ch, 0x00    ; Select cylinder 0
        mov     dh, 0x00    ; Select head 0
        mov     cl, 0x02    ; Start reading from second sector
        int     0x13
        jc      .Error      ; Jump if error (i.e. carry flag set)
        pop     dx
        cmp     dh, al
        jne     .Error
        ret
    .Error:
        mov     si, DISK_ERROR_MESSAGE
        call    Display.String
        ret

DISK_ERROR_MESSAGE:             db "Disk read error!", 0

Mode_32.asm

[bits 32]
[ORG 0x1000]
Start_32:
    pusha
    mov     edx, VIDEO_MEMORY
    xor     eax, eax
    mov     ah, MAGENTA_ON_BLACK
    mov     al, 'Y'
    mov     [edx], ax
    popa
Idle:
    hlt
    jmp     Idle
;=======================================================================
TIMES       512-($-$$)  db  0
;***********************************************************************
%include "Include/Golden_Gate_Intercontinental/Ports/Wired/Video_Graphics_Array/Default.asm"
;***********************************************************************
;//EOF

Finally:

nasm -f bin Mode_32.asm -o Mode_32.vbin -l Mode_32.lst
nasm -f bin Boot.asm -o Boot.vbin -l Boot.lst
cat Boot.vbin Mode_32.vbin > Disk.img
qemu-system-x86_64 -drive file=Disk.img,format=raw,index=0,media=disk
  • 3
    For debugging questions to be on-topic for stack overflow, they need to include a [mcve] of their code directly in the question, not as a link. (You can and should also keep the link to the full project). BTW, the built-debugger in BOCHS is usually the best choice for debugging early boot and the switch to protected mode; it understands segments, unlike attaching GDB to qemu. – Peter Cordes Jan 26 '21 at 23:42
  • @Peter Cordes ... thank you so much for your response. I never tried BOCHS before. So the actual problem is Qemu emulator! Ok ... I need to try with BOCHS and see the result. Actually, the code is same, got from OS Dev Wiki, and no problem, I am adding code. –  Jan 27 '21 at 00:16
  • 1
    Just to be clear, QEMU emulates fine. The advantage is that BOCHS has a better *debugger* to let you see what's happening. Make sure you include the exact commands you used to build code into a binary as part of your [mcve], especially if you're using code from a wiki example that's supposed to work. – Peter Cordes Jan 27 '21 at 00:26
  • Ok, I have done. I've added my minimal reproducible example. –  Jan 27 '21 at 01:06
  • Some emulators don't emulate the `hlt` instruction correctly; simply remove it, so you stop in an endless loop. – Martin Rosenau Jan 27 '21 at 07:37
  • Yes, I've removed unnecessary used ‘HLT’ instruction. But, I think that the actual problem is in my file 'Mode_32.asm'. There are two concepts, I found out: Modern x86 Assembly, 32 bit and 2) The 32 bit x86 C Calling Convention. So I am in progress now. –  Jan 28 '21 at 00:05
  • 16 bits and 64 bits operations, working awesome. But the hell is that 32 bits operation, I am stuck here badly. ... WoW, that means, 16 bits and 64 bits is my friend, and the 32 bits is my enemy! ... really, it's awesome. –  Jan 29 '21 at 07:09

0 Answers0