Problem dropping down to real mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Problem dropping down to real mode

Post by nexos »

Hello,
I am working on a bootloader, and am doing the high level C part. I am making that will drop down to real mode. After debugging, I see that it jumps to a bogus memory location, and locks up the computer. It gets to 16 bit PMode fine, but when I far jump to real modeis when it occurs. Here is the code:

Code: Select all


pstack dd 0                         ; PMode state variables
pmodeGdt:
    dw 0
    dd 0

; Writes a char to screen

global _IoWriteChar                  ; Used in C

_IoWriteChar:
    pushad                      ; Push regs on stack
    cli
    mov dword [pstack], esp     ; Save state
    sgdt [pmodeGdt]
    jmp 0x18:pmode16            ; Go to 16 bit pmode
bits 16
pmode16:
    mov eax, cr0                ; get cr0
    and al, 0xFE                ; Turn off PE bit
    mov cr0, eax                ; Enter into real mode
    jmp 0xA00:rmode - 0xA000
rmode:
    
    cli
    hlt
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bzt
Member
Member
Posts: 1584
Joined: Thu Oct 13, 2016 4:55 pm
Contact:

Re: Problem dropping down to real mode

Post by bzt »

nexos wrote:Hello,
I am working on a bootloader, and am doing the high level C part.
Not entirely sure what you mean by that. Are you writing your bootloader in high level C you mean?
nexos wrote:I am making that will drop down to real mode. After debugging, I see that it jumps to a bogus memory location
This is most likely because you haven't set up the segment registers properly. Using "jmp A00:x" would need ORG 0 in your code. Oh, and you MUST restore IDT to IVT before you cloud use BIOS interrupts.

This is a working example (fasm syntax sorry), I keep CS to zero and I don't touch IDT in protmode, so it's still pointing to IVT:

Code: Select all

prot_realmodefunc:
            cli
            ;get return address
            pop         ebp
            ;save stack pointer
            mov         dword [hw_stack], esp
            jmp         CODE_BOOT:.back ;load 16 bit mode segment into cs
            USE16
.back:      mov         eax, CR0
            and         al, 0FEh        ;switching back to real mode
            mov         CR0, eax
            xor         ax, ax
            mov         ds, ax          ;load registers 2nd turn
            mov         es, ax
            mov         ss, ax
            jmp         0:.back2
.back2:     mov         sp, word [hw_stack]
            sti
            jmp         bp
Cheers,
bzt
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: Problem dropping down to real mode

Post by nexos »

Ok that makes sense! Thank you!
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Post Reply