1

I've problem. Last days I'm playing with GDT, A20 and protected mode. I have this simple code for GDT:

gdt_start:
gdt_null:
    dd 00000000h
    dd 00000000h

gdt_code:
    dw 0xFFFF
    dw 0
    db 0
    db 10011010b
    db 11001111b
    db 00000000b

gdt_data:
    dw 0xFFFF       
    dw 0                
    db 0                
    db 10010010b            
    db 11001111b            
    db 0

gdt_end:
gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

install_gdt:
    cli;
    pusha
    lgdt [gdt_ptr]
    sti
    popa

    ret

As you can see it's very simple. Here's my A20 enabling:

ena20:
    mov al, 0xDD
    out 0x64, al
    ret

And part of second stage code:

    call install_gdt
    call ena20

    cli
    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3
;-------------------------------------------
;STAGE3
;-------------------------------------------
BITS 32
stage3:
    ;mov ax, 0x10
    ;mov ds, ax
    ;mov ss, ax
    ;mov es, ax
    ;mov esp, 90000h

    ;mov edi, 0xB8000
    ;mov byte [edi], 'A'

    jmp $

I tried to go step-by-step. I can successfuly load GDT into it's register, enable A20 and go to protected mode. But when I'm trying to jmp 0x8:stage3, I'm getting error from VirtualBox:

A critical error has occurred while running the virtual machine and
the machine execution has been stopped.

(virtual machine state is now 'Guru Meditation') Does anybody know where is problem? What should I do to make it working? Please help.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
user35443
  • 6,309
  • 12
  • 52
  • 75
  • You can't just switch to protected mode in a virtual machine, you have to negotiate with the host. DPMI is the standard (well, was), no idea if VirtualBox implements it. http://en.wikipedia.org/wiki/DPMI – Hans Passant Aug 07 '12 at 12:51
  • I don't understand. What should I use? I'm not very good in english phrases... – user35443 Aug 07 '12 at 13:21
  • @HansPassant You can just switch to protected mode in a VM. If it's a usable x86 VM, of course. DPMI was an easy-to-use way of doing it (and much more) in DOS (and Windows). DOS, however, is not in the scope of the question. – Alexey Frunze Aug 07 '12 at 19:07
  • This is old, and I see you are still active on SO.By any chance were you using an ORG of 0x0 (or not specifying one at all) and setting your segments to 0x07c0 in the real mode code that wasn't shown? – Michael Petch Mar 07 '19 at 22:16
  • 1
    @MichaelPetch can't remember, really, hah. I think I somehow sorted it out in the end, switching to bochs for debugging. – user35443 Mar 08 '19 at 11:30

1 Answers1

1

Here:

gdt_ptr:
    dw gdt_end - gdt_data - 1
    dd gdt_start

Why is the GDT size from gdt_data to gdt_end and yet the start is at gdt_start?

Also, how about the real-mode segment in which the GDT is contained? How do you "include" it in the value of gdt_start?

Here:

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    jmp 0x8:stage3

BITS 32
stage3:

You want stage3 in a segment whose base is 0 according to the relevant GDT entry. Is that the case? IOW, is the value of stage3 equal to the physical address of the code at this label?

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Why is the GDT size from gdt_data to gdt_end and yet the start is at gdt_start? -repaired, still not working – user35443 Aug 07 '12 at 13:17
  • ...is the value of stage3 equal to the physical address of the code at this label? -yes – user35443 Aug 07 '12 at 13:17
  • You want stage3 in a segment whose base is 0 according to the relevant GDT entry. Is that the case? - don't understand this question – user35443 Aug 07 '12 at 13:17
  • Assemblers assemble code into segments or sections. Every piece of code or data has an address (offset) relative to the beginning of its containing segment/section. Your labels are these offsets. Every offset is only a portion of a physical/virtual address. Segment descriptors (and real-mode segments) provide another portion, the segment base address. If enabled, page translation adds yet another layer of indirection on top of that. You have to take proper care of all these pieces of addresses. You have to remember that x86 code generally is NOT position-independent. – Alexey Frunze Aug 07 '12 at 19:16