procedure is not returning correctly

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
shahzad

procedure is not returning correctly

Post by shahzad »

in the code given below .i'm trying first to switch to protected mode .then i call a procedure named "real mode" .this procedure switches to real mode ,calls a bios interrupt,switches back to protected mode and then returns.
But the problem is that when processor reaches on line numbered 6 it resets,instead of returning to calling point.
please tell what's causing the problem.
actually i'm doing all that to call bios interrupts while my kernel is in protedted mode.
in future i'll call fuction "realmode" from C code to carry out some I/O stuff unless i write my own drivers.

Code: Select all

????????????????????????
[SECTION .text]
[ORG 0x7c00]
[BITS 16]
???  cli
                 xor ax,ax
                 mov ds,ax
                 lgdt [gdtr]
1:              mov dx,cs
???  mov eax,cr0
???  or al,1
???  mov cr0,eax

        jmp SYS_CODE_SEL:do_pm
[BITS 32]
do_pm:???

                mov ax,SYS_DATA_SEL
??? mov ds,ax??????
??? mov ss,ax
??? mov es,ax
??? mov fs,ax
??? mov ax,LINEAR_SEL
             mov gs,ax
             mov byte [gs:0xB80A0],'r'
2:          call  realmode
             mov ax,0x0000
             mov gs,ax
             mov byte [gs:0xB80A0],'Z'
hang1:
             jmp hang1
realmode:

               jmp REAL_CODE_SEL:do_16
[BITS 16]
do_16:
                mov ax,REAL_DATA_SEL
???mov ds,ax
???mov ss,ax
               lea bx,[do_rm]
3:             push dx
                push bx
???mov eax,cr0
???and al,0xFE
???mov cr0,eax
                retf            
do_rm:

               mov ax,cs
???mov ds,ax
???mov ss,ax
???mov es,ax
???mov fs,ax
???mov gs,ax
???sti
                mov al,'S'
                mov ah,0eh
                int 10h

                mov ah,0x00
5:             int 16h

                cli
                xor ax,ax
                mov ds,ax
                lgdt [gdtr]
???
                 mov eax,cr0
??? or al,1
??? mov cr0,eax
                jmp SYS_CODE_SEL:do_pm1
[BITS 32]
do_pm1:  
                  mov ax,SYS_DATA_SEL
???  mov ds,ax??????
???  mov ss,ax
???  mov es,ax
???  mov fs,ax
???  mov ax,LINEAR_SEL
???  mov gs,ax
                  mov byte [gs:0xB80A0],'O'
       
 6:              ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
gdtr:???
dw gdt_end - gdt - 1???
???dd gdt?????????

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;global descriptor table (GDT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; null descriptor
gdt:???dw 0?????????
???dw 0?????????
???db 0?????????
???db 0?????????
???db 0?????????
???db 0?????????
; linear data segment descriptor
LINEAR_SEL???equ???$-gdt
???dw 0xFFFF??????
???dw 0?????????
???db 0
???db 0x92?????????
???db 0xCF?????????
???db 0
; code segment descriptor
SYS_CODE_SEL???equ???$-gdt
gdt1:???dw 0xFFFF
???dw 0?????????
???db 0
???db 0x9A?????????
???db 0xCF
???db 0
; data segment descriptor
SYS_DATA_SEL???equ???$-gdt
gdt2:???dw 0xFFFF
???dw 0?????????
???db 0
???db 0x92?????????
???db 0xCF
???db 0
REAL_CODE_SEL???equ???$-gdt
gdt3:???dw 0xFFFF
???dw 0?????????
???db 0
???db 0x9A?????????
???db 0?????????
???db 0
REAL_DATA_SEL???equ???$-gdt
gdt4:???dw 0xFFFF
???dw 0?????????
???db 0
???db 0x92?????????
???db 0?????????
???db 0
gdt_end:




User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:procedure is not returning correctly

Post by Pype.Clicker »

shahzad wrote:

Code: Select all

2:          call  realmode
             mov ax,0x0000
             mov gs,ax
             mov byte [gs:0xB80A0],'Z'
First, i'd say that its pretty risky to use the *same* stack for both real and protected mode. A more clean way to proceed would be to give both mode a dedicated stack and use the correct stack with something like "lea esp, [end_of_pmode_stack]" after having initialized ss.

Also, you should be aware that if the code would have return from (6) to (2), trying to write a byte at 0x0000 : 0xb80a0 will definitely lead to a General Protection Fault.

Code: Select all

do_16:
                mov ax,REAL_DATA_SEL
   mov ds,ax
   mov ss,ax
               lea bx,[do_rm]
3:             push dx
                push bx
   mov eax,cr0
   and al,0xFE
   mov cr0,eax
                retf
here's another weird thing ... you're now popping stuff from SS=REAL_DATA_SEL while in real mode !?
More problematic is the fact that you reuse the value of CS you read at startup and combine it with a 0-based offset (assuming CS=0 while it could be 0x7C0!) See Curufir's today post to know why that makes my hair standing on my skin ...

I don't really have a precise idea of what it crashes at (6) rather than earlier or later ... do you have a particular reason to believe that's precisely where it crashes, or is it just due to the fact you do not see the next character appearing on screen ?
If you have information from a virtual machine (ever tried bochs with debugging enabled ?), what do the register dump say ?

For my part, i would recommend you to have a good interrupt/exception catching and register dumps before you try to make much moves between real & protected mode.

Also, did you heard of Virtual Mode already ? if not, i suggest you get a quick look at Tim's tutorial about implementing VM86 and maybe read a few more chapters of the Intel Manual ... This is just a suggestion, of course, and you may have very valid reason to keep away from Virtual mode.
shahzad

Re:procedure is not returning correctly

Post by shahzad »

if i add following lines before instruction "ret", code works fine.

Code: Select all

hang2:
jmp hang2
that's why i'm saying that "ret" instruction is not getting
correct address to return.
Curufir

Re:procedure is not returning correctly

Post by Curufir »

Ok, assuming you haven't trashed your stack at some point (You definitely want to look into having separate Real and Protected mode stacks) and the ret works fine you run into this problem.

Code: Select all

            mov ax,0x0000
            mov gs,ax
            mov byte [gs:0xB80A0],'Z'
You're still in PMode at this point, which means you're loading gs with the NULL selector and trying to reference memory through it. Everything falls down at this point.
shahzad

Re:procedure is not returning correctly

Post by shahzad »

both of you were right in pointing out that i was moving wrong descriptor in gs.
i've corrected the problem.now code is working fine.
as you mentioned, i'll certainly consider having different
stacks for real and protected modes in future.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:procedure is not returning correctly

Post by Pype.Clicker »

shahzad wrote: i'll certainly consider having different
stacks for real and protected modes in future.
wise move. Also do consider the use of a virtual PC (bochs/vmware) that could execute your bootsector step by step and report more accurate error conditions ...
Post Reply