Assembly enter protected mode and jump back to real mode

4

I am developing a toy OS in assembly and I have a problem when switching from protected mode back to real mode. I have successfully switched to protected mode, called the kernel that writes text to [0xb8000] video memory, returned to the caller and (probably) switched back to real mode. I am trying to use bios interrupts from real mode so I don't have to write my own device drivers.

Interrupts however don't seem to be executed after switching back to real mode. They don't crash the system as they would in protected mode so I guess I am in real mode.

minrep.asm (bootloader)

boot.header:
[BITS 16]
[ORG 0x7c00]
mov ax, cs
mov ds, ax
xor ax, ax
mov ds, ax
cli
mov ss, ax
mov sp, 0x7c00
sti
call main
jmp $
disk.read_sectors:
reset:
xor ax,ax
int 0x13
jc reset
floppy:
xor bx,bx
mov ah,0x2
mov al, [esp+6]
mov cx,[esp+4]
mov dh,0x0
mov dl, 0x80
mov bx, ds
mov es, bx
mov bx, [esp+2]
int 0x13
jc error
mov ax, 0
ret
error:
mov ax, 1
ret
main:
push word 16 ; 16 sectors for stage2
push word 2 ; starts at sector 2
push word 0x1000 ; into 0x1000 memory buffer
call disk.read_sectors
pop bx
pop bx
pop bx
jmp 0000:0x1000
mov ax, 0
ret
footer:
times 510-($-boot.header) db 0
dw 0xAA55

minrep_st2.asm (stage2, enter prot and back to real)

[BITS 16]
[ORG 0x1000]

stage2.header:

mov ax, cs
mov ds, ax
jmp stage2.main

stage2.main:

mov al, 'B'
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10

call switch_to_protected
switch_to_protected:


            [ bits 16 ]

            cli

            switch_to_pm:

                lgdt [ gdt_descriptor ]
                mov eax , cr0
                or eax , 0x1
                mov cr0 , eax
                jmp CODE_SEG:init_pm

            [ bits 32 ]

            init_pm:

                   mov ax, DATA_SEG
                mov ds, ax
                mov ss, ax
                mov es, ax
                mov fs, ax
                mov gs, ax
                mov ebp , 0x90000
                mov esp , ebp

                sti






[BITS 32]
switch_to_real:


mov [0xb8000], byte 'D'

[BITS 32]
cli

mov eax, cr0
and eax, 0x7FFFFFFF    ; clear PG bit
mov cr0, eax

xor     eax,eax         ; A convenient zero
mov     cr3,eax         ; Flush the TLB

mov eax, cr0
and eax, 0xFFFFFFFE    ; clear PE bit
mov cr0, eax

lidt [idtr]

jmp 0:continue

[BITS 16]

continue:

sti

mov al, 'C'
mov ah, 0x0E
mov bh, 0x00
mov bl, 0x07
int 0x10

hlt


GDT:


            idtr:
            dw 0x3ff
            dd 0

            gdt_start:

                gdt_null:
                    dd 0x0 ;
                    dd 0x0

                gdt_code:
                    dw 0xffff
                    dw 0x0
                    db 0x0
                    db 10011010b ; 1 st flags , type flags
                    db 11001111b ; 2 nd flags , Limit ( bits 16 -19)
                    db 0x0

                gdt_data:
                    dw 0xffff
                    dw 0x0
                    db 0x0
                    db 10010010b ; 1 st flags , type flags
                    db 11001111b ; 2 nd flags , Limit ( bits 16 -19)
                    db 0x0

                gdt_end:

                gdt_descriptor:
                    dw gdt_end - gdt_start - 1
                    dd gdt_start

            CODE_SEG equ gdt_code - gdt_start
            DATA_SEG equ gdt_data - gdt_start

stage2.footer:
times 8192-($-stage2.header) db 0

how to compile:

nasm.bat minrep.asm -o disk_p1.bin
nasm minrep_st2.asm -o disk_p2.bin
copy /b disk_pt1.bin + disk_pt2.bin disk.img
call qemu disk.img

EDIT:

if i only do this to go protected, then movin to 0xb800 in real mode does clear the first character but doesn't print it correctly (blank char instead of byte 'Z')

        [ bits 16 ]

    cli

    switch_to_pm:

        lgdt [ gdt_descriptor ]
        mov eax , cr0
        or eax , 0x1
        mov cr0 , eax
        jmp CODE_SEG:init_pm

    [ bits 32 ]

    init_pm:

the print char 'Z' after sti in continue:

mov ax, 0xb800; 
mov es, ax; 
mov [es:0000], byte 'Z'
assembly
kernel
nasm
x86-16
bootloader
asked on Stack Overflow Feb 24, 2020 by DrCarnivore • edited Feb 24, 2020 by DrCarnivore

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0