flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Back to Real Mode from Protected Mode?

Author
Thread Post new topic Reply to topic
kake_zinger



Joined: 15 Jul 2004
Posts: 59
kake_zinger 15 Jul 2004, 14:06
How do I go back from protected mode to real mode?

I've tried to implement the guidelines found in IA-32 Intel Architecture Software Developer's Manual Volume3: System Programming Guide, Chapter 9 Processor Management and Initialization, 9.9.2 Switching Back to Real-Address Mode, but without much success.

I've begun to feel that the manual either omits something very important or is outright faulty. Of course, being a beginner with assembly, I've felt this way about many things and been proven wrong before.. Smile

Why go back to real mode? It started as a quest to be able to use some int functions, fdd especially, but has taken on a life of its own simply because the Intel manual states that it should be possible. And if it should, it really should.

The code below resets the computer whenever it gets to realmode: and a jump of any kind is performed. This could mean that the way the segments are set up is faulty, but I cannot see where, I've never done anything like this before. Any help would be very welcome.

The GDT and IDT entries for the 16-bit segments are

cseg16 dw 0ffffh,0,9b00h,0040h ;16b code 0-0ffffh, 1 byte granularity
dseg16 dw 0ffffh,0,9300h,0040h ;16b data 0-0ffffh, 1 byte granularity
idtr16 dw 1023,0,0

The default interrupt vector table has not been tampered with and should have the same addresses as at power-on.

The rest of the code (this is not all of it, just the part dealing with going back to real mode) should be rather self-explanatory. I hope. Just a beginner here, bear with me!

Code:
pregorealmode:
    jmp     cseg16:gorealmode   ;Far jump, changes cs to cseg16 (?)
;pregorealmode_end:

gorealmode:
.irqreset:                         ;Set irqs back to originals
 mov     al,11111111b            ;Irqs 7-0 disabled
  out     21h,al
;     mov     al,11111111b            ;Irqs 15-8 disabled
 out     0a1h,al                 ;Now no external interrupts coming
  cli                             ;Don't process external interrupts

     mov     al,00010001b            ;ICW4 needed, cascaded pic's
       out     20h,al                  ;8259 pic 1, master
 out     0a0h,al                 ;8259 pic 2, slave

      mov     al,8                    ;Irq 0-7 to interrupts 8-0fh
        out     21h,al                  ; (base int for irq0 to Cool
  mov     al,70h                  ;Irq 8-15 to interrupts 70h-77h
     out     0a1h,al

 mov     al,00000100b            ;Master: b2 set, slave pic on irq 2
     out     21h,al
      mov     al,00000010b            ;Slave: b1 set, slaved on master irq 2
  out     0a1h,al

 mov     al,00000001b            ;b0 set, 8086 mode
  out     21h,al
      out     0a1h,al

.pitreset:                           ;Program PIT back to original values
        mov     al,00110110b            ;Counter 0, square wave, binary
     out     43h,al
      mov     cx,0ffffh               ;Default rate 18 Hz
 mov     al,cl
       out     40h,al
      mov     al,ch
       out     40h,al

  mov     ax,dseg16               ;Set segments for real mode
 mov     ds,ax
       mov     es,ax
       mov     fs,ax
       mov     gs,ax
       mov     ss,ax
       mov     sp,7c00h
    mov     bp,7c00h
    
    lidt    [idtr16]                ;Load real mode 16bit idtr

      and     eax,0
       or      eax,01100000000000000000000000010000b   ;"Reset" state for CPU
    mov     cr0,eax
     jmp     far 0:realmode              ;Start real mode
;gorealmode_end:

use16

realmode:
  mov     ax,0
        mov     ds,ax
       mov     es,ax
       mov     fs,ax
       mov     gs,ax
       mov     ss,ax
       mov     sp,7c00h
    mov     bp,7c00h

        mov     al,10111110b            ;Irqs 6,0 enabled
   out     21h,al
      mov     al,11111111b            ;Irqs 15-8 disabled
 out     0a1h,al
     sti                             ;Process external interrupts

;Any code after this doesn't execute too well, whether the interrupts are turned
; back on or not. Especially jumps cause a reboot.    
Post 15 Jul 2004, 14:06
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4 15 Jul 2004, 18:19
This is how i go from pmode to real to do vesa int's, it works, but may not be the best?
I call this proc from pmode.
Code:
Real_Mode_int:        pushad        cli        jmp 20H:do_1611use16do_1611:        mov ax,28H    mov ds,ax     mov ss,ax     nop; push real-mode CS:IP     mov bx,[RealModeCS]                  ; Store this in realmode push bx       lea bx,[do_rm]        push bx; clear PE [protected mode enable] bit and return to real mode        mov eax,cr0        and al,0xFE   mov cr0,eax   retf            ; jumps to do_rm;*************************** 16-bit real mode again *********************; restore real-mode segment register valuesdo_rm:        mov  byte [es:dword 0xB8008],'E'        mov ax,cs   mov ds,ax     mov ss,ax     nop   mov es,ax     mov fs,ax     mov gs,ax; point to real-mode IDTR  lidt [ridtr]; re-enable interrupts        push  cs    pop   ds        push  ds        pop   es        mov ax,0xB800   mov es,ax        sti;****************************** call real mode int ********************************        mov  ax,4f02h                   ; set vesa screen mode        mov  bx,0x4112                  ; 640*480*24        int  10h;****************************** go back to pmode ********************************        cli        lgdt  [gdtr]                    ; VLoad the GDTR with the base address and limit of the GDT        lidt  [idtr]    mov   eax,cr0                   ; Set the PE [protected mode enable] bit in register CR0      or    al,1    mov   cr0,eax     jmp   sys_code:do_pm11          ; jumps to do_pm;******************************;    32-bit protected mode      ;;******************************use32do_pm11:        xor   edi,edi        xor   esi,esi  mov   ax,sys_data        mov   ds,ax        mov   ss,ax        nop      mov   es,ax   mov   fs,ax   mov   gs,ax        mov   ax,linear_sel    mov   es,ax        sti        popad        ret    

NOTE: in realmode i do this.
Code:
        xor   ebx,ebx        mov   bx,ds                                                  ; BX=segment     shl   ebx,4                                                  ; BX="linear" address of segment base  mov   eax,ebx mov   [sys_code_1 + 2],ax                                    ; set base address of 32-bit segments    mov   [sys_data_1 + 2],ax     mov   [Real_code_1 + 2],ax                                   ; set base address of 16-bit segments    mov   [Real_data_1 + 2],ax    shr   eax,16  mov   [sys_code_1 + 4],al     mov   [sys_data_1 + 4],al     mov   [Real_code_1 + 4],al    mov   [Real_data_1 + 4],al  mov   [sys_code_1 + 7],ah     mov   [sys_data_1 + 7],ah     mov   [Real_code_1 + 7],ah    mov   [Real_data_1 + 7],ah        add   ebx,gdt                                               ; EBX=linear address of gdt mov   [gdtr + 2],ebx  add   ebx,idt - gdt                                       ; EBX=linear address of idt mov   [idtr + 2],ebx        cli   mov   ax,cs   mov   [RealModeCS],ax    


ASHLEY4
Post 15 Jul 2004, 18:19
View user's profile Send private message Reply with quote
Gomer73



Joined: 29 Nov 2003
Posts: 151
Gomer73 15 Jul 2004, 18:45
I think probably the issue is that you need to jump to a 16 bit protected mode code segment before taking the jump to real mode.

Maybe if you don't do that you can run 32-bit real mode? Would be interesting but kind of useless.
Post 15 Jul 2004, 18:45
View user's profile Send private message Reply with quote
Octavio



Joined: 21 Jun 2003
Posts: 366
Location: Spain
Octavio 15 Jul 2004, 23:01
[quote="kake_zinger"]How do I go back from protected mode to real mode?

> Of course, being a beginner with assembly, I've felt this way about >many things and been proven wrong before.. Smile

Try again when you become an expert Smile

>The rest of the code (this is not all of it, just the part dealing with going >back to real mode) should be rather self-explanatory.

But is not self-explanatory, did you tell to the assembler where the program is loaded 'ORG 7c00h '
is the program runing in protected or real mode?
have you loaded the GDT?


.irqreset: ;Set irqs back to originals
cli ;Don't process
;this is enought forget about the pic and the idt by now

mov eax,cr0
and eax,-2
mov cr0,eax
jmp far 0:realmode ;Start real mode
;gorealmode_end:

use16

realmode:
mov ax,0
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov sp,7c00h
mov bp,7c00h

sti

;Process external interrupts

;Any code after this doesn't execute too well, whether the interrupts are
How do you know the exact point where program crash?
Post 15 Jul 2004, 23:01
View user's profile Send private message Visit poster's website Reply with quote
kake_zinger



Joined: 15 Jul 2004
Posts: 59
kake_zinger 20 Jul 2004, 13:28
Ashley4, thanks a ton for posting your code, I'll study it and get back if need to.

Octavio, the code I posted is just a small part of larger part and everything works all ok, don't worry about that. I'll check out if just doing what you suggest would be enough. I know that any 16-bit code most probably crashes due to any jump, which would mean my segments are screwed somehow, just have no idea how. Been testing it with code that sets RGB values for the background color, loops, delays etc.

Thanks everybody, any little bit helps a lot. All I want to do is to be able to save stuff to my floppy without writing a floppy driver of my own.
Post 20 Jul 2004, 13:28
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4 20 Jul 2004, 16:17
Hi kake_zinger, If you take a look at the old "v2os" code (made in tasm) ,they do just that
eg: go to real mode from pmode for read/write to floppy etc, it may be Worth a look.

Here is there site http://www.v2os.cx/old/

ASHLEY4.
Post 20 Jul 2004, 16:17
View user's profile Send private message Reply with quote
Gomer73



Joined: 29 Nov 2003
Posts: 151
Gomer73 22 Jul 2004, 16:05
Do you happen to have the old source code(v0.64) for V2OS?
When I checked out the site, they had the new source code(v0.70), but not the old.

I noticed the PCI stuff seemed to work a little better on the old stuff as well as that is what all programs were written for.

...Gomer73
Post 22 Jul 2004, 16:05
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4 22 Jul 2004, 20:15
Try this Gomer73.

ASHLEY4.
Post 22 Jul 2004, 20:15
View user's profile Send private message Reply with quote
Gomer73



Joined: 29 Nov 2003
Posts: 151
Gomer73 26 Jul 2004, 23:56
Thanks Ashley4, took me awhile to get to a computer I could download it on.

Looks like a neat little OS. Too bad they stopped development.

...Gomer73
Post 26 Jul 2004, 23:56
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4 27 Jul 2004, 01:36
Hi Gomer73,
They have not stopped developing, just run out of asm programmer's like you, This is the new site see the forum, they are looking for asm progammer's
http://www.v2os.cx/
Y not offer your assembly skills Smile.

ASHLEY4.
Post 27 Jul 2004, 01:36
View user's profile Send private message Reply with quote
kake_zinger



Joined: 15 Jul 2004
Posts: 59
kake_zinger 30 Jul 2004, 13:31
Hi everybody, I have recently found out that I'm an unbelievable retard. I need to set up 16-bit segments for real mode. So I handcraft the segment desriptors carefully by hand. Finally there's the 16/32 mode bit. Which I carefully...set to 32. 0040h in my original GDT. Live and learn..

Thanks to everybody who helped. Looking at Ashley4's code made me realize some smaller things that are not just quite right, and it pointed out one key aspect: the Intel manual instructs one to set up IDT after coming back to protected mode. But I couldn't get this to work. But loading idt just after gdt, like Ashley4 did, works perfectly.

Well, my project continues, I hope to be able to put something out to public when summer ends or so. Although a FASM port seems to be somewhat distant still, as I'm still learning programming.
Post 30 Jul 2004, 13:31
View user's profile Send private message Reply with quote
ASHLEY4



Joined: 28 Apr 2004
Posts: 376
Location: UK
ASHLEY4 30 Jul 2004, 14:52
kake_zinger, The code i posted has a small bug, if you reprogram pic's in your os, on coming back from real-mode the keyboard did not work right.
To fix this at the begining of the going back to real-mode proc, you need to mask IRQ and on coming back at the end to unmask IRQ.
Useing this code:
Code:
mask_irqs:        cli        mov  al,255                                       ; mask all irqs        out  0xa1,al        out  0x21,al        retunmask_irqs:        mov  al,0                                         ; unmask irq's        out  0xA1,al        out  0x21,al        sti        ret    


ASHLEY4.
Post 30 Jul 2004, 14:52
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.